Question: Where does p
get it's value from below and why does it happen?
Consider this irb session:
me@somewhere:~$ irb
irb(main):001:0> a
NameError: undefined local variable or method `a' for main:Object
from (irb):1
irb(main):002:0> foo
NameError: undefined local variable or method `foo' for main:Object
from (irb):2
irb(main):003:0> p
=> nil
irb(main):004:0> p.class
=> NilClass
irb(main):005:0>
I never defined p
- so why is it nil valued? Neither a
nor foo
were recognized so what's special about p
? I also didn't find anything listed under Kernel#p
Context: I'm reading the so-called "28 bytes of ruby joy" and assumed p
was a variable, as in: def p.method_missing *_
...
(Don't worry: I'm not going to actually define method_missing on nil everywhere... just studying some ruby code...)
p
is just a method on Kernel
which calls inspect
on its arguments, producing human-readable representations of those objects. If you give it no arguments, it prints nothing. Regardless of what you pass it, though, it returns nil
. See Kernel#p
and Object#inspect
.
Power tip: In Ruby 1.9, when you have a method and you don't know where it came from, use the method
method:
ruby-1.9.1-p378 > method(:p)
=> #<Method: Object(Kernel)#p>
Putting it together one step at a time, we read this as:
p # We found a method called p.
#p # It's an instance method.
Object ... #p # It's available on Object.
Object(Kernel)#p # It came from the Kernel module.
Update: The OP provided some context from this article, where the author claims that your life will be easier if you add a method_missing
to nil
, by doing the following:
def p.method_missing*_;p;end
This somewhat obfuscated code should be read as:
def
), called method_missing
. This overrides the default method_missing
handler on Object
, which simply raises a NoMethodError
when it encounters a method it doesn't understand.p
.*
) and stores them in a variable called _
.p
.The second bullet is the tricky part here. def p.method_missing
means one of two things, depending on context:
p
which is in scope here.p
which is in scope, and which is passed no arguments.With def p.method_missing
, we mean, "this method is being defined on the object which is the result of calling p
with no arguments". In this case, that is NilClass
; if you call p
with no arguments, you get nil
. So this is just a short, hacky way to define a method on NilClass
.
Note: I definitely recommend against defining a method_missing
on nil
. This is a silly and dangerous tactic to use for the sake of saving a few lines of code, because it changes the behavior of nil
. Don't do it!
p
is a method which prints the inspect
value of its arguments and returns nil. Without arguments it simply does nothing.
Its documentation is under Kernel#p
, not Kernel::p
(because it's an instance method of Kernel).
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