代码之家  ›  专栏  ›  技术社区  ›  Sancarn

attr_访问器在哪里定义?

  •  0
  • Sancarn  · 技术社区  · 6 年前

    目前正在使用 Ripper lex() 方法。但目前 attr_accessor 定义为标识符…我想是因为这是一种方法。

    在哪里 附件存取器 定义?如果我知道它的定义在哪里,我可以很容易地为类似它的方法设置异常。

    2 回复  |  直到 6 年前
        1
  •  1
  •   ForeverZer0    6 年前

    它在 Module 类。 (Documentation Link)

    编辑: 为了使答案更完整,它是 私有的 方法 模块 类,这意味着您不能用接收器调用它,需要打开类才能使用它(或使用类似hack的方法) send eval

    class MyClassOrModule
      attr_accessor :foobar
    end 
    

    不能将其调用为 MyClassOrModule.attr_accessor .正如您在下面的评论中发现的, Module.private_instance_methods 将显示它的存在。

        2
  •  0
  •   Cary Swoveland    6 年前

    对, attr_accessor 在类中定义 Module ( Module#attr_accessor 但是一开始如何找到它呢?不得不问别人,或者谷歌搜索,这不是一个非常有效的方法。

    我们可以利用这个方法 Method#owner . 1个

    owner 响应方法对象(类的实例 Method ,而不是方法名,它们是符号。为什么?因为许多模块/类具有相同符号名的方法。例如, String ,请 Array Hash 都有一个名为 :[] .因此,我们不能问鲁比在哪里 :[] 已定义。但是,我们可以问,方法在哪里

    m = [1,2,3].method(:[])
      #=> #<Method: Array#[]
    

    定义,即,

    m.owner
      #=> Array
    

    决定 m 利用这个方法 Object#method .

    或者,我们可以写

    m = Array.instance_method(:[])
      #=> #<UnboundMethod: Array#[]>
    m.owner
      #=> Array
    

    这就利用了这个方法 Module#instance_mathod .

    注意,在第一种情况下,方法 :[] 跳跃 以…为例 数组 [1,2,3] ,而在第二种情况下 :[] 未绑定到的任何特定实例 数组 ,所以它被称为 UnboundMethod .不管怎样,我们都能看到 Array#[] 在中定义 数组 (即,它不是从祖先那里继承的)。

    让我们考虑另一个例子。

    我们知道 3.zero? #=> false ,但找不到实例方法 :zero? 在课堂上 Integer .那么,它在哪里?我们可以写:

    m = 3.method(:zero?)
      #=> #<Method: Integer(Numeric)#zero?>
    

    m = Integer.instance_method(:zero?)
      #=> #<UnboundMethod: Integer(Numeric)#zero?>
    

    然后

    m.owner
      #=> Numeric
    

    啊哈!它的定义在 Numeric 的超类 Integer ,请 Float ,请 Rationale Complex .

    注意,在计算中 ,显示的消息包括, "Integer(Numeric)" .甚至在计算之前 m.owner 这告诉我们主人是 数字 .相反,在寻找 数组[] 信息很简单 "Array" .和往常一样有用,Ruby在所有者不是接收者的类时为所有者加上括号。 method 或是接收的类 instance_method .

    现在让我们找到类方法的所有者 :attr_accessor .我们知道这种方法适用于每个类(例如, Class.new.methods.include?(:attr_accessor) #=> true ,所以我们可以写,比如,

    m = Class.method(:attr_accessor)
      #=> #<Method: Class.attr_accessor>
    m.owner
      #=> Module
    

    自从 Class 它本身就是一个类,但是我们可以写,比如,

    m = Regexp.method(:attr_accessor)
      #=> #<Method: Regexp.attr_accessor>
    m.owner
      #=> Module
    

    甚至

    m = Class.instance_method(:attr_accessor)
      #=> #<UnboundMethod: Class(Module)#attr_accessor>
    m.owner
      #=> Module
    

    每个类的最后一个因为方法(它是 等级 )是的实例方法 等级 .

    1如果忘记了实例方法的位置 主人 是定义的,请记住它是在方法上定义的,这些方法是类的实例 方法 .