2012-03-02 10 views
1

RuNubieはこちら。私はnet/IMAPライブラリを使ってgmailにログインするクラスLoginを持っています。私がメールボックスにいくつかの「もの」を行います他のクラスに取り組んでいます、そして、ルビ変数のスコープがクラスを超えて

a = Login.new("username", "gmail.com", "passw") 

:何が起こっていることは、私のような、そのクラスの新しいインスタンスを作成することです。問題は、ログインで定義した@imap変数が消滅したように見えることです(スコープが設定されているため)。

これは@imapは、ログインクラスで宣言されている方法です。だから、この @imap = Net::IMAP.new('imap.gmail.com',993,true,nil,false)

@today = Date.today 
    @received_today = imap.search(["SINCE", @today.strftime("%d-%b-%Y")]).count.to_s 

は...エラーを返します。これらは私がこれで周りを遊んでいる間に得た2つのエラーです。私はimapを使用するときに最初の1があり、もう一つは、私は@imapをしようとすると、次のとおりです。

NameError: undefined local variable or method `imap' for #<Object:0x10718d2a8> 
NoMethodError: undefined method `search' for nil:NilClass 

このような状況に対処するためのベストプラクティスは何ですか?私がNet :: IMAPの新しいインスタンスを作成しているクラスと同じクラスで「やる」メソッドを定義する唯一のソリューションですか? をグローバル変数$imapとして悪い習慣と宣言していますか?とても混乱していますが、答えは非常にシンプルで明白ですが、私はそれを見ていません。ありがとう!

答えて

1

この:まあ、そこにはimapは、その時点でスコープ内にありませんので、あなたはNameErrorを取得し、ため

@received_today = imap.search(["SINCE", @today.strftime("%d-%b-%Y")]).count.to_s 

は動作しません。あなたはこのようにそれをしようとすると:インスタンス変数のような@imapは、自動的に最初の使用時に作成され、nilように初期化されているので、

@received_today = @imap.search(["SINCE", @today.strftime("%d-%b-%Y")]).count.to_s 

あなたはNoMethodErrorを取得します。あなたの本物の@imapは他のオブジェクトにありますので、他の場所では@imapと呼ぶことはできません。

私は、あなたがより多くのこのような構造をしたいと思う:

class User 
    def imap 
     if([email protected]) 
      @imap = Net::IMAP.new('imap.gmail.com', 993, true, nil, false) 
      # and presumably an @imap.authenticate too... 
     end 
     @imap 
    end 
end 

class OtherOne 
    def some_method(user) 
     @today = Date.today 
     @received_today = user.imap.search(["SINCE", @today.strftime("%d-%b-%Y")]).count.to_s 
    end 
end 

あなたのユーザーの内側にローカライズNet::IMAPを保ち、他のオブジェクトは、単純なアクセサメソッドを提供することにより、それを使用してみましょう。

ああ、そのグローバル$imapアイデア、私はちょうど私がグローバルがほとんど常に本当に悪い考えであるとは思わなかったふりをします。

+0

ありがとう!これは理にかなっているので、基本的にクラスUserのインスタンスは、OtherOneクラスのsome_methodに引数として渡されます。私はこのように、別のクラスがクラスUserを呼び出すたびにNet :: IMAPがログインし、メールボックスを認証することに懸念しています。多くの他のクラス/メソッドがメールボックスに "やる"ことを試み続けて、毎回ログインしなければならない場合、遅くなるかもしれないようです。あなたの答えに基づいて、net/IMAPでログインしてオープンにする方法はないように思えます。 – krapdagn

+1

@krapdagn: 'Net :: IMAP。'new'はユーザごとに一度だけ呼び出され、' imap'は既存の '@imap'を返します。 '@imap'が切断されると、いくつかのロジックを再接続させたいかもしれません。 –

1

かなりのMUが掲示するものと同じであるUserクラス、中にIMAP変数を定義するための短い方法:

class User 
    def imap 
     @imap ||= Net::IMAP.new... 
    end 
end 
+0

ありがとうございます。私はRubyが問題を解決するために複数の方法を持っていることを愛しています。 ||のような新しいことを学ぶのは良い= – krapdagn

関連する問題