country =
[\"UK\", \"US\", \"RS\", \"EU\", \"UK\", \"US\"].
group_by{ |e| e }.
keep_if{ |_, e | e.length > 1 }
#⇒ {\"UK\"=>[\"UK\", \"UK\"], \"US\"=>[
There are three answers to this on two levels.
The first answer is on the level of the Ruby language: there is no use of the underscore in Ruby. It has no meaning. It is just a legal identifier like any other legal identifier. It could have been named foo
or bar
instead, and it would not in any way change the meaning of this code.
The second answer is on the level of the Ruby community: in the Ruby community, the underscore is used to communicate to other programmers reading the code "I need to put an identifier here because the rules of the Ruby language force me to, but I am not actually interested in it, I will in fact never use it." So, it has no meaning to Ruby, but it does have meaning to Ruby programmers. It's just like methods ending in !
or ?
: they have no special meaning, they are just used to communicate intent from one Ruby programmer to another.
The third answer is again on the level of the Ruby language: because of #2, there were two changes made in Ruby 1.9+ that codify the uses of the underscore as an "ignore me" identifier:
_
do not generate warnings._
can be used multiple times.See:
#!/usr/bin/ruby -w
foo = nil
bar = nil
baz = nil
Running:
./test.rb
./test.rb:3: warning: assigned but unused variable - foo
./test.rb:4: warning: assigned but unused variable - bar
./test.rb:5: warning: assigned but unused variable - baz
But:
#!/usr/bin/ruby -w
_foo = nil
_bar = nil
_ = nil
Running:
./test.rb
And:
#!/usr/bin/ruby -w
def foo(bar, bar) end
Running:
./test.rb
./test.rb:3: duplicated argument name
def foo(bar, bar); end
[The second bar
is underlined in the console, which is hard to reproduce here.]
But:
#!/usr/bin/ruby -w
def foo(_bar, _bar) end
Running:
./test.rb
So, the only difference between an underscore and no underscore is that the underscore turns off certain errors and warnings, in line with its common usage within the Ruby community.
This convention is generally also respected by linters, static analyzers, editors, and IDEs providing semantic analysis of Ruby code, e.g. IDEs that highlight and warn about unused variables will not do so for variables whose name begins with or is _
.
By convention, underscore is used as a variable name for a value that is not used. Unlike other variable names, it can be used multiple times in a single parallel assignment.
In this particular case, the filter in the block is not interested in the key of the hash, but only the value of the hash, which is an array generated by group_by
.