加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 将initialize()args设置为属性的快捷方式?

发布时间:2020-12-16 22:57:34 所属栏目:百科 来源:网络整理
导读:这是一种常见的初始化模式: def initialize(title,val,type) @title,@val,@type = title,typeend 是否存在等同于“获取每个参数,创建同名属性,并将属性设置为参数值”的快捷方式? 我正在寻找一种无宝石的解决方案. 解决方法 这是你如何做到这一点.将为每个
这是一种常见的初始化模式:
def initialize(title,val,type)
  @title,@val,@type = title,type
end

是否存在等同于“获取每个参数,创建同名属性,并将属性设置为参数值”的快捷方式?

我正在寻找一种无宝石的解决方案.

解决方法

这是你如何做到这一点.将为每个初始化参数创建一个实例变量和一个关联的读/写访问器,变量具有相同的名称,以@开头,并且每个实例变量将被赋予相关参数的值.

class MyClass
  def initialize(< arbitrary parameters >)
    self.class.params.each { |v|
      instance_variable_set("@#{v}",instance_eval("#{v}")) }

    < other code >
  end

  @params = instance_method(:initialize).parameters.map(&:last)
  @params.each { |p| instance_eval("attr_accessor :#{p}") }

  class << self
    attr_reader :params
  end  

  < other code >     
end

class MyClass
  def initialize(a,b,c)
    self.class.params.each { |v|
      instance_variable_set("@#{v}",instance_eval("#{v}")) }
  end

  @params = instance_method(:initialize).parameters.map(&:last)
  @params.each { |p| instance_eval("attr_accessor :#{p}") }

  class << self
    attr_reader :params
  end  
end

MyClass.methods(false)
  #=> [:params]
MyClass.instance_methods(false)
  #=> [:a,:a=,:b,:b=,:c,:c=]

m = MyClass.new(1,2,3)
m.a #=> 1
m.b #=> 2
m.c #=> 3
m.a = 4
m.a #=> 4

说明

解析类MyClass时,为类实例变量@params分配一个数组,其元素是initialize的参数.这是可能的,因为在解析开始@params = …的代码时创建了方法初始化.

方法Method#parameters用于获得初始化的参数.对于上面的例子,

instance_method(:initialize).parameters
  #=> [[:req,:a],[:req,:b],:c]]

所以

@params = instance_method(:initialize).parameters.map(&:last)
  #=> [:a,:c]

然后我们创建读/写访问器:

@params.each { |p| instance_eval("attr_accessor :#{p}") }

和@params的读访问器,供初始化使用:

class << self
  attr_reader :params
end

创建MyClass的实例my_class时,传递给MyClass.new的参数值将传递给initialize.通过类实例变量@params初始化然后循环并设置每个实例变量的值.在这个例子中,

MyClass.new(1,3)

调用initialize(a,c)where

a => 1
b => 2
c => 3

我们有:

params = self.class.params
  #=> [:a,:c]

params.each { |v| instance_variable_set("@#{v}",instance_eval("#{v}")) }

对于params的第一个元素(:a),这是:

instance_variable_set("@a",instance_eval(a) }

这是:

instance_variable_set("@a",1 }

导致@a被分配1.

请注意@params的访问器不是必需的:

class MyClass
  def initialize(a,c)
    self.class.instance_variable_get(:@params).each { |v|
      instance_variable_set("@#{v}",instance_eval("#{v}")) }
  end

  @params = instance_method(:initialize).parameters.map(&:last)
  @params.each { |p| instance_eval("attr_accessor :#{p}") }
end

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读