有没有一种简单的方法来遍历attr_reader属性并设置它们?
class Foo
attr_reader :bar, :baz, ...
def initialize attrs
@bar = attrs[:bar]
@baz = attrs[:baz]
.
.
.发布于 2021-07-11 18:22:09
如果希望散列键与属性名匹配,一种可能是继承结构:
class Foo < Struct.new(:bar, :baz, keyword_init: true) # Note the "keyword_init" parameter
end
puts Foo.new(bar: 42, baz: :foo).bar
# => 42结构还将创建公共编写器,因此如果希望它们不是公共编写器,则必须将它们设置为私有
FOO_ATTRS = [:bar, :baz]
class Foo < Struct.new(*FOO_ATTRS, keyword_init: true) # Note the "keyword_init" parameter
# Make method 'my_attribute=' private if needed
private *FOO_ATTRS.map { |attr| "#{attr}=" }
end
puts Foo.new(bar: 42, baz: :foo).bar如果要重命名不同属性名称的散列键:
class Foo
INITIAL_ATTRS = {
foo: :@bar,
bar: :@baz
}
attr_reader *(INITIAL_ATTRS.values.map { |k| k.to_s.delete('@').to_sym })
def initialize attrs
attrs.slice(*INITIAL_ATTRS.keys).each do |var, value|
instance_variable_set(INITIAL_ATTRS[var], value)
end
end
end编辑
另一种可能是使用私有attr_writer,这样你就不必处理@ tricks了
class Foo
INITIAL_ATTRS = {
foo: :bar,
bar: :baz
}
attr_reader *(INITIAL_ATTRS.values)
def initialize attrs
attrs.slice(*INITIAL_ATTRS.keys).each do |var, value|
send("#{INITIAL_ATTRS[var]}=", value)
end
end
private
attr_writer *(INITIAL_ATTRS.values)
end请注意,如果您不想将foo转换为bar,则可以使用数组而不是INITIAL_ATTRS的散列。这将通过删除.values和.keys来简化代码
class Foo
INITIAL_ATTRS = [:foo, :bar]
attr_reader *INITIAL_ATTRS
def initialize attrs
attrs.slice(*INITIAL_ATTRS).each do |var, value|
send("#{var}=", value)
end
end
private
attr_writer *INITIAL_ATTRS
endhttps://stackoverflow.com/questions/68332510
复制相似问题