在Ruby中实现访问器方法

时间:2012-03-02 16:30:47

标签: ruby scope imap accessor

这是一个跟进问题:ruby variable scoping across classes。这个解决方案在概念上对我有意义,但我无法让它发挥作用。想到可能有更多代码,有人可以帮助我。

我有一个类Login,它声明一个新的IMAP类,验证并选择一个邮箱。

然后我尝试创建一个单独的类,它将在邮箱中“执行操作”。例如,计算收到的电子邮件数量。问题是@imap Net::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类的方法,而不是单独的类。我真的想把它变成一个单独的类,所以我可以更容易地划分... 谢谢!

2 个答案:

答案 0 :(得分:0)

好的---在墙上撞了很多头后,我开始工作了。

将这三种方法添加到类Login:

  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使用:

只需将其添加到类登录中,然后可以在login.imap.search#stuff中说class Stat毫无问题。

答案 1 :(得分:0)

另一种有效且不需要定义get_var方法的方法:

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