Ruby自我和方法定义

  发布于 2023-02-13 16:07

我会用Kernel#set_trace_func方法,向你解释幕后发生了什么.首先看下面的代码和输出:

trace = lambda do |event,file,line,id,binding,klass|
    p [event,File.basename(file),line,id,binding,klass]
end


set_trace_func trace

class MyClass
  def self.bar;end
  def one
    def two
    end
  end
end

obj = MyClass.new
obj.one
obj.instance_eval do
  def three
  end
end

输出:

-----------------
----------------
-----------------
-----------------
-----------------
----------------- # part A
["c-call", "test.rb", 9, :singleton_method_added, #, BasicObject]
["c-return", "test.rb", 9, :singleton_method_added, #, BasicObject]
["line", "test.rb", 10, nil, #, nil]
["c-call", "test.rb", 10, :method_added, #, Module]
["c-return", "test.rb", 10, :method_added, #, Module]
----------------------------- # part B
["line", "test.rb", 16, nil, #, nil]
["c-call", "test.rb", 16, :new, #, Class]
["c-call", "test.rb", 16, :initialize, #, BasicObject]
["c-return", "test.rb", 16, :initialize, #, BasicObject]
["c-return", "test.rb", 16, :new, #, Class]
---------------------------
---------------------------
--------------------------- # part C
["c-call", "test.rb", 11, :method_added, #, Module]
["c-return", "test.rb", 11, :method_added, #, Module]
--------------------------- # part D
["line", "test.rb", 18, nil, #, nil]
["c-call", "test.rb", 18, :instance_eval, #, BasicObject]
["line", "test.rb", 19, nil, #, nil]
["c-call", "test.rb", 19, :singleton_method_added, #, BasicObject]
["c-return", "test.rb", 19, :singleton_method_added, #, BasicObject]
["c-return", "test.rb", 18, :instance_eval, #, BasicObject]

说明:

看看A部分下面的5行.它只是告诉我们Ruby何时会在类中找到关键字,它会将该方法作为实例方法添加到该类中.这是通过调用hook方法完成的.同样的解释是在C部分下面的两行.defModule#method_added

现在里面发生了obj.instance_eval {..}什么?

好的,如果你看看D部分下面的行,这将被清除.从最后一行,第一行第二行开始查看.在instance_eval 块中,通过调用hook方法将def third原因third添加为singleton_method对象的一部分.obBasicObject#singleton_method_added

这就是MRI的编写方式.

1 个回答
  • 我会用Kernel#set_trace_func方法,向你解释幕后发生了什么.首先看下面的代码和输出:

    trace = lambda do |event,file,line,id,binding,klass|
        p [event,File.basename(file),line,id,binding,klass]
    end
    
    
    set_trace_func trace
    
    class MyClass
      def self.bar;end
      def one
        def two
        end
      end
    end
    
    obj = MyClass.new
    obj.one
    obj.instance_eval do
      def three
      end
    end
    

    输出:

    -----------------
    ----------------
    -----------------
    -----------------
    -----------------
    ----------------- # part A
    ["c-call", "test.rb", 9, :singleton_method_added, #<Binding:0x83ab2b0>, BasicObject]
    ["c-return", "test.rb", 9, :singleton_method_added, #<Binding:0x83aaeb4>, BasicObject]
    ["line", "test.rb", 10, nil, #<Binding:0x83aab80>, nil]
    ["c-call", "test.rb", 10, :method_added, #<Binding:0x83aa900>, Module]
    ["c-return", "test.rb", 10, :method_added, #<Binding:0x83aa07c>, Module]
    ----------------------------- # part B
    ["line", "test.rb", 16, nil, #<Binding:0x83a976c>, nil]
    ["c-call", "test.rb", 16, :new, #<Binding:0x83a9488>, Class]
    ["c-call", "test.rb", 16, :initialize, #<Binding:0x83a90a0>, BasicObject]
    ["c-return", "test.rb", 16, :initialize, #<Binding:0x83a8e20>, BasicObject]
    ["c-return", "test.rb", 16, :new, #<Binding:0x83a8b28>, Class]
    ---------------------------
    ---------------------------
    --------------------------- # part C
    ["c-call", "test.rb", 11, :method_added, #<Binding:0x83a7de0>, Module]
    ["c-return", "test.rb", 11, :method_added, #<Binding:0x83a79f8>, Module]
    --------------------------- # part D
    ["line", "test.rb", 18, nil, #<Binding:0x83a7034>, nil]
    ["c-call", "test.rb", 18, :instance_eval, #<Binding:0x83a6c10>, BasicObject]
    ["line", "test.rb", 19, nil, #<Binding:0x83a65f8>, nil]
    ["c-call", "test.rb", 19, :singleton_method_added, #<Binding:0x83a61d4>, BasicObject]
    ["c-return", "test.rb", 19, :singleton_method_added, #<Binding:0x83a5ef0>, BasicObject]
    ["c-return", "test.rb", 18, :instance_eval, #<Binding:0x83a5d4c>, BasicObject]
    

    说明:

    看看A部分下面的5行.它只是告诉我们Ruby何时会在类中找到关键字,它会将该方法作为实例方法添加到该类中.这是通过调用hook方法完成的.同样的解释是在C部分下面的两行.defModule#method_added

    现在里面发生了obj.instance_eval {..}什么?

    好的,如果你看看D部分下面的行,这将被清除.从最后一行,第一行第二行开始查看.在instance_eval 块中,通过调用hook方法将def third原因third添加为singleton_method对象的一部分.obBasicObject#singleton_method_added

    这就是MRI的编写方式.

    2023-02-13 16:10 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有