现在是时候让它更简短了:
class Foo
attr_accessor :a, :b, :c, :d, :e
def initialize(a, b, c, d, e)
@a = a
@b = b
@c = c
@d = d
@e = e
end
end
我们有'attr_accessor'来生成getter和setter。
我们有什么可以根据属性生成初始化程序的东西吗?
现在是时候让它更简短了:
class Foo
attr_accessor :a, :b, :c, :d, :e
def initialize(a, b, c, d, e)
@a = a
@b = b
@c = c
@d = d
@e = e
end
end
最简单的:
Foo = Struct.new( :a, :b, :c )
生成访问器和初始化器。您可以使用以下方式进一步自定义您的类:
Foo = Struct.new( … ) do
def some_method
…
end
end
class Foo < Struct.new(:a, :b, :c)
进行定义。 - Andrew Marshalldef_initializer
的东西:# Create a new Module-level method "def_initializer"
class Module
def def_initializer(*args)
self.class_eval <<END
def initialize(#{args.join(", ")})
#{args.map { |arg| "@#{arg} = #{arg}" }.join("\n")}
end
END
end
end
# Use it like this
class Foo
attr_accessor :a, :b, :c, :d
def_initializer :a, :b, :c, :d
def test
puts a, b, c, d
end
end
# Testing
Foo.new(1, 2, 3, 4).test
# Outputs:
# 1
# 2
# 3
# 4
eval
的字符串形式来要求正确的元数。你可能应该将此方法放在 Module
或 Class
的单例类上,因为除了类之外的对象实例上使用这个方法没有太多意义。 - Phrogz它很容易使用:声明式意味着通过将哈希传递给构造函数来定义对象属性,该函数将设置相应的ivars。
Class Foo
constructor :a, :b, :c, :d, :e, :accessors => true
end
foo = Foo.new(:a => 'hello world', :b => 'b',:c => 'c', :d => 'd', :e => 'e')
puts foo.a # 'hello world'
如果您不想使用访问器生成ivars,可以省略:accessors => true
希望这可以帮到您 /Salernost
class Module
def initialize_with( *names )
define_method :initialize do |*args|
names.zip(args).each do |name,val|
instance_variable_set :"@#{name}", val
end
end
end
end
initialize_with:a,:b
+ Foo.new(1,2,3,4,5)
将不会产生错误。 - Casperclass Foo
class InvalidAttrbute < StandardError; end
ACCESSORS = [:a, :b, :c, :d, :e]
ACCESSORS.each{ |atr| attr_accessor atr }
def initialize(args)
args.each do |atr, val|
raise InvalidAttrbute, "Invalid attribute for Foo class: #{atr}" unless ACCESSORS.include? atr
instance_variable_set("@#{atr}", val)
end
end
end
foo = Foo.new(a: 1)
puts foo.a
#=> 1
foo = Foo.new(invalid: 1)
#=> Exception
def initialize(*args)
...@a,@b,@c,@d,@e = args
def initialize(*args)
...@a,@b,@c,@d,@e = args
- Muhammad Umer