鉴于以下课程:
class Test
attr_accessor :name
end
Run Code Online (Sandbox Code Playgroud)
当我创建对象时,我想执行以下操作:
t = Test.new {Name = 'Some Test Object'}
Run Code Online (Sandbox Code Playgroud)
目前它导致名称nil仍然存在.这可能吗?
注意:我不想添加初始化程序.
Nic*_*ume 18
好,
我想出了一个解决方案.它使用初始化方法但另一方面完全按照您的要求进行操作.
class Test
attr_accessor :name
def initialize(init)
init.each_pair do |key, val|
instance_variable_set('@' + key.to_s, val)
end
end
def display
puts @name
end
end
t = Test.new :name => 'hello'
t.display
Run Code Online (Sandbox Code Playgroud)
开心吗?:)
使用继承的替代解决方案.注意,使用此解决方案,您无需显式声明attr_accessor!
class CSharpStyle
def initialize(init)
init.each_pair do |key, val|
instance_variable_set('@' + key.to_s, val)
instance_eval "class << self; attr_accessor :#{key.to_s}; end"
end
end
end
class Test < CSharpStyle
def initialize(arg1, arg2, *init)
super(init.last)
end
end
t = Test.new 'a val 1', 'a val 2', {:left => 'gauche', :right => 'droite'}
puts "#{t.left} <=> #{t.right}"
Run Code Online (Sandbox Code Playgroud)
正如其他人所提到的,最简单的方法是定义一个initialize方法.如果您不想这样做,可以让您的类继承自Struct.
class Test < Struct.new(:name)
end
Run Code Online (Sandbox Code Playgroud)
所以现在:
>> t = Test.new("Some Test Object")
=> #<struct Test name="Some Test Object">
>> t.name
=> "Some Test Object"
Run Code Online (Sandbox Code Playgroud)
有一种通用的方法来执行复杂的对象初始化 - 传递块和必要的操作.可以在对象的上下文中评估此块,因此您可以轻松访问所有实例变量,方法等.
继续你的榜样
class Test
attr_accessor :name
def initialize(&block)
instance_eval(&block)
end
end
Run Code Online (Sandbox Code Playgroud)
然后
t = Test.new { @name = 'name' }
Run Code Online (Sandbox Code Playgroud)
要么
t = Test.new do
self.name = 'name'
# other initialization, if needed
end
Run Code Online (Sandbox Code Playgroud)
请注意,这种方式不需要复杂的initialize方法更改(事实上,这是一行的).
您指示的代码正在将参数传递到函数中initialize。您肯定必须使用initialize,或者使用更无聊的语法:
test = Test.new
test.name = 'Some test object'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12020 次 |
| 最近记录: |