Have you ever been confused by the __underscores__ required by some of __RUBY__'s features? You can get it right with this overview of all of "super snake" keywords and methods.
There are three different types of underscore-wrapped syntaxes in the Ruby core language:
- Object methods and
- Kernel methods.
Let us take a look at each of them, and understand the motivations behind. Or directly jump to:
Keywords (Built into Ruby Syntax)
These are directly translated by the Ruby interpreter: You cannot use meta-programming with these, since they will always return the corresponding value directly:
Returns the current source file's name. Might be special value for unusual invocations:
|File, directly executed||path name, can be relative|
|File, required / loaded||absolute path|
Returns the line number in the current source file. Also works in IRB and with code executed with
$ ruby -e, STDIN or
Returns the source file's encoding, as specified per magic comment. The default source file encoding is UTF-8. The important thing to understand is that this value should correspond to the actual encoding of the source file, so to change the source encoding, it is not enough to just change the magic comment, you will also need to convert the source file.
You should also note that this is unrelated to some other global encoding configurations, which serve different purposes:
__END__ (at beginning of line)
A special syntax which will end the source file earlier and create big data.
These special Kernel methods are lowercased to highlight the fact that they are actually just methods and no built-in keywords.
__method__ and __callee__
Both return the current method's name, but they differ in a detail: When using a method alias,
__callee__ will return the aliased method name, while
__method__ would return the original name:
def example! p [__method__, __callee__] end alias test! example! example! # => [:example!, :example!] test! # => [:example!, :test!]
File.dirname(File.realpath(__FILE__)), which is the absolute path of the directory of the current source file.
While it also works in IRB, it will return
nil in eval,
$ ruby -e, and STDIN contexts.
Both of the following methods are so important that every object (even those that inherit from BasicObject directly) should have. This is why they got some underscore companions.
Returns the object id, just like Object#object_id. It mainly exists for historical reasons, most people use
__send__ method is an alias of the Object#send, which dynamically calls the method given as a symbol argument. Its purpose is that you should still be able to use the send functionality in case someone redefines the
send method. The interpreter will issue a warning¹ should you try to redefine or remove it:
warning: redefining `__send__' may cause serious problems
Nevertheless, it is probably not a good idea either to redefine non-underscore-wrapped
send, since a lot of meta-programming relies on it…
¹ This is not true for
__id__ - Ruby will not complain if you choose to redefine it. It will complain for
- Episode 5: Constant Shadows (even another way Ruby uses underscores)
- Episode 19: Symbolic Reservations (in certain cases, symbols with underscores can be special)