【问题标题】:Implementing accessor methods in Ruby在 Ruby 中实现访问器方法
【发布时间】:2012-03-02 16:30:46
【问题描述】:

这是对ruby variable scoping across classes 的后续问题。该解决方案在概念上对我来说很有意义,但我无法让它发挥作用。想也许有更多的代码有人可以帮助我。

我有一个类 Login,它声明一个新的 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 并让它不抛出“无方法搜索”错误。同样,另一个问题包含伪代码和如何使用访问器方法来执行此操作的高级解释,但无论我尝试了多少小时(整晚都在),我都无法实现它......

我能想到的就是我在高层做错了,stat计算需要是Login类的方法,而不是单独的类。然而,我真的很想把它变成一个单独的类,这样我就可以更容易地划分...... 谢谢!

【问题讨论】:

  • 我认为你对什么是实例变量有一个相当基本的误解。对象的每个实例都有一组完全独立的实例变量。
  • 那么有没有办法将类Login的实例作为参数传递给Stat类中的方法?我同意这对我来说是一个根本的误解。看来我应该只有一个类,一个登录方法、一个邮箱方法和一堆“做事”方法。这是最佳做法吗?

标签: ruby scope imap accessor


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2010-10-12
      • 1970-01-01
      • 2015-07-26
      • 1970-01-01
      • 2020-02-14
      • 1970-01-01
      • 2020-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多