2012-03-02 63 views
1

这是后续问题:ruby variable scoping across classes。这个解决方案对我来说在概念上是有意义的,但我无法让它工作。想想也许有更多的代码可以帮助我。在Ruby中实现访问器方法

我有一个类声明一个新的IMAP类,进行身份验证,并选择一个邮箱的登录。

然后,我试图创建一个单独的类,将在邮箱中“做东西”。例如,计算收到的电子邮件数量。问题是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并让它不会抛出“无法搜索”错误。再次,另一个问题包含pseudo_code和一个关于如何使用访问器方法来做到这一点的高层次解释,但是我无法实现它,无论我尝试了多少个小时(已经整夜)...

所有我能想到的是,我在高级别做这个错误,并且stat计算需要是Login类的一个方法,而不是一个单独的类。我真的想把它作为一个单独的课程,但是,所以我可以更容易地划分... 谢谢!

+0

我认为你有一个实例变量就是一个相当根本性的误解。对象的每个实例都有一组完全独立的实例变量。 – 2012-03-02 17:55:30

+1

因此,没有办法将类Login的实例作为参数传递给类Stat中的方法?我同意这种感觉就像是对我的一个基本误解。看起来我应该只有一个类,有一个登录方法,一个邮箱方法和一些“do stuff”方法。这是最佳做法吗? – krapdagn 2012-03-02 21:07:02

回答

0

确定---在墙上撞了很多头之后,我得到了这个工作。

添加这三种方法来上课登录:

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 

现在这种实际工作,并没有说未定义的方法searchimap

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

我很确定有一种方法可以使用attr_accessor也要做到这一点,但无法弄清楚语法。无论如何,这是有效的,并使我能够在类Stat中使用来自类Login的@imap var,因此我可以使用它为“do_stuff”写入方法。感谢您的帮助,请不要犹豫,告诉我这是糟糕的Ruby或不是最佳实践。我很想听听Ruby的方式来实现这一点。

编辑为attr_accessorattr_reader使用:

只需将它添加到类登录,然后可以说在class Stat没有问题login.imap.search#stuff

0

另一种办法是可行,不需要定义get_var方法:

b.instance_variable_get("@imap") # where b = class instance of login