2012-03-02 16 views
1

これは、ruby variable scoping across classesへのフォローアップの質問です。このソリューションは概念的には理にかなっていますが、それを動作させることはできません。誰かが私を助けることができるより多くのコードを考えた。Rubyでアクセサメソッドを実装する

新しいIMAPクラスを宣言し、認証し、メールボックスを選択するクラスLoginがあります。

私はメールボックスに「する」という別のクラスを作成しようとしています。たとえば、受信した電子メールの数を計算します。問題は、Net::IMAP@imapインスタンスがLoginクラスからStatクラスに渡されないということです。新しいクラスのimap.searchのメソッドエラーは発生しません。私はメールボックスで「何かする」必要があるたびに、再度ログインして再認証したくない。私は他のスレッドでは、ソリューションを実装しようとしているが、動作するように見えることはできません。

ここLoginクラスです:

class Login 
    def initialize(user, domain, pass) 
    @username = user 
    @domain = domain 
    @pass = pass 

    #check if gmail or other domain 
    gmail_test = @domain.include? "gmail.com" 
    if gmail_test == true 
     @imap = Net::IMAP.new('imap.gmail.com',993,true,nil,false) 
     @imap.login(@username + "@" + @domain, @pass) 
    else 
     @imap = Net::IMAP.new("mail." + @domain) 
     @imap.authenticate('LOGIN', @username + "@" + @domain, @pass) 
    end 
    return self 
    end 

    #enable mailbox select  
    def mailbox(box) 
    @mailbox = box 
    @mailbox_array = @imap.list('','*').collect{ |mailbox| mailbox.name } #create array of mailboxes 
    @matching_mailbox = @mailbox_array.grep(/#{@mailbox}/i) #search for mailbox along list 
    if @matching_mailbox.empty? == true #if no results open INBOX 
     @mailbox = "INBOX" 
     @imap.examine(@mailbox) 
    else 
     @imap.examine(@matching_mailbox.first.to_s) #if multiple results, select first and examine 
     @mailbox = @matching_mailbox.first.to_s 
    end 
    return self 
    end  
end 

私が言うことができるようにしたい:

Login.new("user", "domain", "pass").mailbox("in") 

、その後のようなもの:

class Stat 
    def received_today() 
    #emails received today 
    @today = Date.today 
    @received_today = @imap.search(["SINCE", @today.strftime("%d-%b-%Y")]).count.to_s 
    puts @domain + " " + @mailbox.to_s + ": " + @received_today + " -- Today\n\n" #(" + @today.strftime("%d-%b-%Y") + ") 
    end 
end 

そして

を呼び出すことができるが、

Stat.new.received_todayとし、「メソッドなし検索」エラーをスローしないようにしてください。繰り返しになりますが、もう1つの疑問には、疑似コードとこれを行うためのアクセサメソッドの使用方法に関する高度な説明が含まれていますが、試した回数にかかわらず実装できません。

私が考えることができるのは、これが間違っていて、統計計算が別のクラスではなくLoginクラスのメソッドでなければならないということです。私は本当にそれを別のクラスにしたいと思っていましたので、私はもっと簡単にコンパートメント化することができました... ありがとう!

+0

私はあなたがインスタンス変数が何であるかのかなり根本的な誤解があると思います。オブジェクトの各インスタンスは、完全に別々のインスタンス変数のセットを持ちます。 –

+1

クラスLoginのインスタンスをクラスStatのメソッドに引数として渡す方法はありませんか?私はこれが私の最後の基本的な誤解のように感じることに同意します。私は、ログインメソッド、メールボックスメソッド、および "do stuff"メソッドのbuchを持つクラスを1つだけ持っているようです。それはベストプラクティスですか? – krapdagn

答えて

0

OK ---壁にたくさんの頭が叩かれた後、私はこれを動作させました。

クラスのログインには、次の3つの方法を追加しました:

def get_imap 
    @imap 
    end 
    def get_domain 
    @domain 
    end 
    def get_mailbox 
    @mailbox 
    end 

変更クラススタットへ:今

class Stat 
     def received_today(login) 
      #emails received today 
     @today = Date.today 
     @received_today = login.get_imap.search(["SINCE", @today.strftime("%d-%b-%Y")]).count.to_s 
     # puts @received_today 
     puts login.get_domain + " " + login.get_mailbox.to_s + ": " + @received_today + " -- Today\n\n" 
     end 
     end 

これは実際に動作する、と言っていないが未定義のメソッドsearchまたはimap

b = Login.new("user", "domain", "pass").mailbox("box") 
c = Stat.new 
c.received_today(b) 

私はattr_accessorを使用する方法があると確信していますこれを行うには、構文を理解することができませんでした。とにかく、これは動作し、私はクラスLoginのクラスLoginの@imap varを使うことができるので、メソッドを "do_stuff"に書くことができます。助けてくれてありがとう、そして、これはひどいRubyかベストプラクティスではないことを私に教えてください。私はこれを達成するためにRubyの方法を聞くのが大好きです。 attr_accessorまたはattr_reader使用する

編集:

だけでクラスログインに追加して、何の問題もなくclass Statlogin.imap.search#stuffを言うことができます。

0

作品とget_varメソッドを定義する必要はありません。別のアプローチ:

b.instance_variable_get("@imap") # where b = class instance of login 
関連する問題