Реализация методов доступа в Ruby - PullRequest
1 голос
/ 02 марта 2012

Это дополнительный вопрос к: области видимости переменной ruby ​​для классов . Решение имеет смысл для меня концептуально, но я не могу заставить его работать. Подумал, может, с большим количеством кода кто-нибудь может мне помочь.

У меня есть класс 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 и не выдавайте ошибку «поиск по методу». Опять же, другой вопрос содержит псевдо-код и высокоуровневое объяснение того, как использовать метод доступа для этого, но я не могу реализовать его независимо от того, сколько часов я пробовал (не спал всю ночь) ...

Все, что я могу думать, это то, что я делаю это неправильно на высоком уровне, и вычисление статистики должно быть методом класса Login, а не отдельным классом. Однако я действительно хотел сделать его отдельным классом, чтобы легче было разделить его на части ... Спасибо!

Ответы [ 2 ]

0 голосов
/ 03 марта 2012

Другой подход, который работает и не требует определения методов get_var:

b.instance_variable_get("@imap") # where b = class instance of login
0 голосов
/ 03 марта 2012

ОК --- После долгих ударов головой о стену, я заставил это работать.

Добавлены эти три метода в класс Login:

  def get_imap
    @imap
  end
  def get_domain
    @domain
  end
  def get_mailbox
    @mailbox
  end

Изменен класс Stat на:

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

Теперь это на самом деле работает и не говорит неопределенный метод search или imap:

b = Login.new("user", "domain", "pass").mailbox("box") 
c = Stat.new
c.received_today(b)

Я почти уверен, что есть способ использовать attr_accessor, но не смог разобраться в синтаксисе.В любом случае, это работает и позволяет мне использовать переменную @imap из класса Login в классе Stat, чтобы я мог писать методы для него "do_stuff".Спасибо за помощь и, пожалуйста, не стесняйтесь сказать мне, что это ужасный Ruby или не лучшие практики.Я хотел бы услышать, как Руби достигнет этого.

Изменить для attr_accessor или attr_reader, использовать:

Просто добавьте его в класс Login и затем без проблем можете сказать login.imap.search#stuff в class Stat.

...