I have a situation where I would like to create a class which accepts many arguments and has setters and getters in the fewest lines of code possible (for maintainability). I thought that using a Struct would be a good idea for this:
Customer = Struct.new(:id, :username, :first_name, :last_name, :address1, ...etc...)
Customer.new(123, 'joe', 'Joe', ...etc...)
However, I don't like having to know the exact order of the attributes. I prefer Ruby 2's keyword arguments feature:
class Customer
attr_accessor :id, :username, :first_name, ...etc...
def initialize(id:, username:, first_name:, last_name:, address1:, ...etc...)
@id = id
@username = username
@first_name = first_name
...etc...
end
end
Customer.new(id: 123, username: 'joe', first_name: 'Joe', ...etc...)
However, writing this all out requires a lot more code and is more tedious. Is there a way to achieve the same thing in a short-hand like the Struct?
In ruby 2.5 you can do the following:
Customer = Struct.new(
:id,
:username,
:first_name,
keyword_init: true
)
Customer.new(username: "al1ce", first_name: "alice", id: 123)
=> #<struct Customer id=123, username="al1ce", first_name="alice">
references:
Cant you just do:
def initialize(hash)
hash.each do |key, value|
send("#{key}=", value)
end
end
UPDATE:
To specify default values you can do:
def initialize(hash)
default_values = {
first_name: ''
}
default_values.merge(hash).each do |key, value|
send("#{key}=", value)
end
end
If you want to specify that given attribute is required, but has no default value you can do:
def initialize(hash)
requried_keys = [:id, :username]
default_values = {
first_name: ''
}
raise 'Required param missing' unless (required_keys - hash.keys).empty?
default_values.merge(hash).each do |key, value|
send("#{key}=", value)
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With