self.class_eval << DEF ... DEF - PullRequest
       13

self.class_eval << DEF ... DEF

2 голосов
/ 10 июня 2009

Я пытаюсь понять эту функцию.

Я вижу, что атрибут и тип передаются методу opal ().

Тогда type_name принимает значение от type, пока type равно Symbol или String. В противном случае метод name вызывается на type. Я полагаю, что метод name похож на метод class, чтобы получить класс аргумента type.

После self.class_eval Я в некотором роде потерян, но, думаю, это определяет, может быть, блок кода, добавляемый в класс, на который ссылается self

Как это работает, я не уверен, хотя.

Буду признателен, если кто-нибудь сможет объяснить, что происходит после self.class_eval << DEF.

    def opal(attr, type)
      self.ds "#{attr}_id"
      type_name = (type.is_a?(Symbol) || type.is_a?(String)) ? type : type.name
      self.class_eval <<DEF
  def #{attr}
    if defined?(@#{attr})
      @#{attr}
    else 
      @#{attr} = if self.#{attr}_id
          #{type_name}.get(self.#{attr}_id)
        else
          nil
        end
    end
  end

  def #{attr}=(value)
    self.#{attr}_id = value.key
    @#{attr} = value
  end
DEF
    end

Ответы [ 2 ]

5 голосов
/ 10 июня 2009

Все, что между <<DEF и DEF - это просто строка, и #{ ... } s работает с этой строкой, как и любая другая.

class_eval заставит интерпретатор работать со строкой в ​​контексте модуля.

Итак, если вы знаете, что такое attr и type, вы можете определить, какой код запускается для добавления методов в класс.

Допустим, attr это "foo", а type это "Bazzle". Запускаемый код будет:

def foo
  if defined?(@foo)
    @foo
  else 
    @foo = if self.foo_id
      Bazzle.get(self.foo_id)
    else
      nil
    end
  end
end

def foo=(value)
  self.foo_id = value.key
  @foo = value
end
3 голосов
/ 10 июня 2009

Чтобы было легче понять, давайте предположим, что значение 'attr' равно 'foo', вот как это выглядит сейчас:

self.class_eval <<DEF
  def foo
    if defined?(@foo) # Return the value of attr if it's defined
      @foo
    else 
      @foo = if self.foo_id
          #{type_name}.get(self.foo_id)
        else
          nil
        end
    end
  end

  def foo=(value) # Define setter
    self.foo_id = value.key
    @foo = value
  end
DEF

Так что это просто определение некоторых методов получения и установки для @foo и оценка их на уровне класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...