I find myself using hash arguments to constructors quite a bit, especially when writing DSLs for configuration or other bits of API that the end user will be exposed to. What I end up doing is something like the following:
class Example
PROPERTIES = [:name, :age]
PROPERTIES.each { |p| attr_reader p }
def initialize(args)
PROPERTIES.each do |p|
self.instance_variable_set "@#{p}", args[p] if not args[p].nil?
end
end
end
Is there no more idiomatic way to achieve this? The throw-away constant and the symbol to string conversion seem particularly egregious.
You don’t need the constant, but I don’t think you can eliminate symbol-to-string:
BTW, you might take a look (if you haven’t already) at the
Structclass generator class, it’s somewhat similar to what you are doing, but no hash-type initialization (but I guess it wouldn’t be hard to make adequate generator class).HasPropertiesTrying to implement hurikhan’s idea, this is what I came to:
As I’m not that proficient with metaprogramming, I made the answer community wiki so anyone’s free to change the implementation.
Struct.hash_initializedExpanding on Marc-Andre’s answer, here is a generic,
Structbased method to create hash-initialized classes: