跨类的ruby变量范围

RuNubie在这里。 我有一个使用net/IMAP库登录gmail的类Login 。 发生的事情是我创建了该类的新实例,例如:

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

然后,我正在研究其他类,这些类会对邮箱做一些“东西”。 问题是我在Login中定义的@imap变量似乎已经消失了(由于我假设的范围)。

这就是在Login类中声明@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 

…返回错误。 这是我在玩这个时遇到的两个错误。 第一个是当我使用imap ,第二个是当我尝试使用@imap

 NameError: undefined local variable or method `imap' for # NoMethodError: undefined method `search' for nil:NilClass 

处理这种情况的最佳做法是什么? 是唯一的解决方案来定义我的方法,在我创建Net :: IMAP的新实例的同一个类中做“填充”? 将@imap声明为全局变量$imap是一种不好的做法吗? 如此困惑,我打赌答案很简单也很明显,但我只是没有看到它。 谢谢!

这个:

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

将无法正常工作,因为在那一点上,范围内没有imap ,因此您得到一个NameError。 当你这样尝试时:

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

您会收到NoMethodError,因为实例变量(如@imap )会在首次使用时自动创建并初始化为nil 。 你真正的@imap在另一个对象中,所以你不能在其他任何地方将它称为@imap

我想你想要一个更像这样的结构:

 class User def imap if(!@imap) @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 ,我只是假装我没有看到,因为全局变量几乎总是一个非常糟糕的主意。

在User类中定义imap变量的更短方法,与发布的内容几乎相同:

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