Reputation: 9298
I've encountered this code when tweaking the ghi
, and I cannot figure out the meaning for passing an object to the ALIASES
object. Could anyone help to explain the [key] if /^\d+$/ === key
line in the following code?
ALIASES = Hash.new { |_, key|
[key] if /^\d+$/ === key
}.update({...})
https://github.com/yangchenyun/ghi/blob/reading/lib/ghi.rb#L119-138
Upvotes: 0
Views: 96
Reputation: 3965
This code sets a default value, that is returned when a not-existing key is accessed.
In this specific case, the default is set to return the given key
inside an Array
, if the given key
is a String
representation of a integer number.
hash = Hash.new do |_, key|
[key] if /^\d+$/ === key
end
hash["foo"].inspect # => nil
hash[123].inspect # => nil
hash["123"].inspect # => ["123"]
Some examples for the regex matching:
/^\d+$/ === 123 # => false
/^\d+$/ === "a123" # => false
/^\d+$/ === "123a" # => false
/^\d+$/ === "1.23" # => false
/^\d+$/ === "123" # => true
And another (simpler) example for a default value:
hash = Hash.new { |_, key| "this key does not exist" }
hash["foo"] # => "this key does not exist"
hash["foo"] = "bar"
hash["foo"] # => "bar"
About the block parameter naming:
You could name the first parameter anything you like, but some developers like to name a unused block operator _
. This way it is clear at the first glance, that you don't care about this parameter.
Upvotes: 3
Reputation: 5398
Here's an excerpt from Ruby documentation for Hash::new:
If obj is specified, this single object will be used for all default values. If a block is specified, it will be called with the hash object and the key, and should return the default value. It is the block’s responsibility to store the value in the hash if required.
In your case it's a block, which defines a default value that will be returned when a key is not found. In this case it'll return it only if the key matches given regular expression /^\d+$/
, and [key]
means it will be returned inside an array.
Upvotes: 0
Reputation: 2258
Please have a look at the Hash::new documentation here. It says:
Returns a new, empty hash. If this hash is subsequently accessed by a key that doesn’t correspond to a hash entry, the value returned depends on the style of new used to create the hash. If a block is specified, it will be called with the hash object and the key, and should return the default value.
So "_" is the value of the object being set, and the author does not care about it. The middle line just checks whether key consists only of numbers and if not, it assigns the key value to an array with this key value. If the key consists only of numbers, it is disregarded.
Ruby's Regexp#=== is just an alias for Regexp#=~.
Just a note - this is a horrible, unreadable piece of code. Just because you can write things like that does not mean you should. Please don't get inspired.
Upvotes: 0
Reputation: 80095
The [key] if /^\d+$/ === key
is the default_proc. It runs everytime when a key is not found in the hash.ALIASES["123"]
would return ["123"]
if "123" is not an existing key.
Upvotes: 2