【问题标题】:How does Ruby use symbols to reference variable names?Ruby 如何使用符号来引用变量名?
【发布时间】:2012-10-06 15:23:55
【问题描述】:

当我们在下面的代码中为name定义getter和setter方法时:

class Animal
    attr_accessor :name
    def initialize(name)
        @name = name
    end
end

内部发生了什么? Ruby 如何获取符号并将其与变量匹配?

【问题讨论】:

    标签: ruby metaprogramming


    【解决方案1】:

    为此它使用instance_variable_getinstance_variable_set

    更新:正如 Andrew Marshall 所说,不完全是。大多数 ruby​​ 核心方法都是用 C 定义的,但结果基本相同。

    可以如下定义attr_accessor和朋友:

    def self.attr_accessor(*names)
      names.each do |name|
        define_method(name) do
          instance_variable_get("@#{name}")
        end
    
        define_method("#{name}=") do |new_value|
          instance_variable_set("@#{name}", new_value)
        end
      end
    end
    

    请注意,我在这里也使用了define_method 来定义访问器方法。

    我建议你看一些关于 ruby​​ 元编程的介绍性文本,例如"Don’t Know Metaprogramming In Ruby?"

    【讨论】:

      【解决方案2】:

      它与变量不匹配,attr_accessor 本质上是这样做的(它实际上是用 C 编写的,但我在这里写的大致是 Ruby 翻译):

      def attr_accessor(var_name)
        ivar_name = :"@#{var_name}"
        define_method(var_name) do
          instance_variable_get ivar_name
        end
        define_method("#{var_name}=") do |value|
          instance_variable_set ivar_name, value
        end
      end
      

      如您所见,它只是使用传递的符号来创建两个方法。它并没有对符号做任何花哨的事情,而且大多只是通过它。另请注意,所有实例变量默认“存在”并设置为nil,所以这永远不会爆炸。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-12
        • 1970-01-01
        • 2021-05-01
        • 2013-06-15
        • 1970-01-01
        • 2018-02-10
        • 2015-09-24
        • 2021-06-01
        相关资源
        最近更新 更多