I know I can use class as Hash key, but is it a good practice? Is there any drawbacks in terms of performance or testing?
{
SomeClassA: 'hash value',
AnotherClass: 'hash value'
}
{
SomeClassA: 'hash value',
AnotherClass: 'hash value'
}
Is actually equivalent to:
{
:SomeClassA => 'hash value',
:AnotherClass => 'hash value'
}
The keys are symbols. In the "new" literal hash syntax keys are just treated as literals which are cast into symbols (provided they are valid syntax).
To use constants, ranges or any other type of object you can dream up as keys you need to use hashrockets:
{
SomeClassA => 'hash value',
AnotherClass => 'hash value'
}
Is it a good practice?
Its a technique that could be used in few limited cases. For example to replace a series of if statements.
def foo(bar)
if bar.is_a? SomeClassA
'hash value'
end
if bar.is_a? AnotherClass
'another value'
end
end
def foo(bar)
{
SomeClassA => 'hash value',
AnotherClass => 'another value'
}[bar]
end
But I would rather use a case statement there anyways as its clearer in intent and more flexible.
Are there any drawbacks in terms of performance or testing?
Each hash you create would have keys that point to the exact same objects in memory just like if you where using symbols.
One big gotcha is that Rails monkey-patches const_missing to autoload files - when you reference a class name rails will load the file from the file system into memory. This is why you declare associations with:
class Foo < ApplicationRecord
belongs_to :bar, class_name: "Baz"
end
It lets Rails instead lazy load Baz when needed. You would do the same with the example above by:
def foo(bar)
{
'SomeClassA' => 'hash value',
'AnotherClass' => 'another value'
}[bar.name]
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