1

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

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

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

这是@imap在 Login 类中声明的方式: @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 #<Object:0x10718d2a8>
NoMethodError: undefined method `search' for nil:NilClass

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

4

2 回答 2

1

这:

@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想法,我只是假装我没有看到这一点,因为全球性几乎总是一个非常糟糕的想法。

于 2012-03-02T04:04:49.593 回答
1

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

class User
   def imap
      @imap ||= Net::IMAP.new...
   end
end
于 2012-03-02T04:43:21.730 回答