跨类的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