self.class_eval << DEF ... DEF

fra*_*anz 2 ruby

我正试图理解这个功能.

我能看到的是属性和类型被传递给opal()方法.

然后type_name需要从它的值type,只要type是一个SymbolString.否则,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
Run Code Online (Sandbox Code Playgroud)

toh*_*lio 5

之间的内容<<DEFDEF只是一个字符串和#{ ... }该字符串像任何其他的工作.

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
Run Code Online (Sandbox Code Playgroud)