Reputation: 769
I'm doing some work in an existing Ruby code base, and I'm quite new to Ruby. I see this initialization idiom pretty often:
def initialize(input)
@number = input[:number]
@color = input[:color]
end
I guess I have two questions. One is whether this is a common idiom and if so, what's good about it? The second is, what is actually happening here? Is the implication that input is an array? A hash? The underlying mechanics aren't clear to me.
Upvotes: 0
Views: 990
Reputation: 87486
Yes, it's common. Generally when you see code like this, it means that input
is a Hash. Occasionally someone might pass in an object that acts like a hash, though, and we can still expect this code to work. We can tell that input
is definitely not an array, because arrays require Integers to be used as their index, but :number
and :color
are Symbols.
Whenever you see something starting with a colon like :number
, that is a Ruby symbol.
Whenever you see something starting with a @
like @number
, that is the name of an instance variable. Instance variables are used to store data inside objects for later use.
Suppose we have a class Foo
defined like this:
class Foo
def initialize(input)
@number = input[:number]
@color = input[:color]
end
end
In this case, we can create a new object like this:
Foo.new(number: 4, color: 'red')
The code above is equivalent to:
input_hash = { :number => 4, :color => 'red' }
Foo.new(input_hash)
One nice thing about this pattern is that you can tell exactly what each input variable is being used for because it will be written next to a descriptive symbol, and also it doesn't matter what order you put the input variables in.
If you want to improve this code, you might consider using a new feature of Ruby called keyword arguments. Alternatively, you might also consider Hash#fetch so you can have more control over what happens when one of the keys is missing, instead of just storing a nil value in your object. I would also recommend that you check the input hash for any unexpected keys and raise an exception if they are found.
Upvotes: 2
Reputation: 160571
Is this a common idiom and if so, what's good about it?
It's not common, but it's acceptable. When there are more than n parameters being passed in, where "n" is often > 3, we should use a hash.
What's good about it? Look at the code. Is it simple and readable? Does it make sense that an input parameter of :number
is being assigned to an instance variable of the same name?
what is actually happening here? Is the implication that input is an array? A hash? The underlying mechanics aren't clear to me.
It's a hash where :number
and :color
are keys.
Upvotes: 1