If I assign a value to the variable pp
and then call pp pp
in the console why doesn't pretty print loop?
$ irb
pp = "hello world"
=> "hello world"
pp pp
"hello world"
=> "hello world"
According to this explanation I think it should
https://blog.brycekerley.net/2014/08/27/Working-with-pp-the-Ruby-Pretty-Printer.html
CodePudding user response:
I'm going far on a limb here (for fun mostly) and guessing you do something like this
>> pp "this is a test"
"this is a test"
=> "this is a test"
>> pp = pp
=> nil
>> pp pp
nil
=> nil
>> pp "this is another test"
"this is another test"
=> "this is another test"
So here's what happens
pp = pp
You've created a local variable pp
which got assigned a value of whatever pp
method returned (nil
in this case)
>> pp pp
here you call pp
method and passing it pp
variable, which holds nil
>> pp "this is another test"
"this is another test"
=> "this is another test"
you still can call pp
method as usually.
Not sure why would you expect it to loop. Expressions are evaluated (right to left in general), so they will evaluate eventually. No infinite loops should generally happen. Take this example:
x = y = z = x
It will first evaluate right-most x
(which has not been defined, so defaults to nil
, so next step conceptually will be:
x = y = z = nil
assigns nil to z, and result of this evaluation is also nil
x = y = nil
assigns nil to y and so on...
CodePudding user response:
Ruby is an interpreted language, meaning that, instead of compiling, it executes the code as written, interpreting the code line by line, word by word (or rather token by token).
When ruby interpreter encounters a line pp pp
, it needs to resolve two tokens. First one is clearly a method as it takes an argument, the other one can be either a method OR local variable (there are no brackets nor arguments).
So, during execution, ruby will start resolution from the second token. When it is not clear whether token denotes variable or method, ruby always searches for variable first. In this case, the variable is there as you assigned a value to pp
creating a local variable (let's say by pp = 1
).
Then ruby has still to process the second token, but now it looks like pp(1)
(because first token has been resolved already). In this case this is, again, clearly a method so ruby just send a pp
message to self
(which in this context is (main) object). Method pp
is defined on Kernel, so each object - including (main)
can access it.
The key point here is to understand that you have not overridden method pp
- that method is still there. The only thing that happened is different resolution of pp
token. Even with pp
hidden (or shadowed) by local variable, you can still invoke it either by using explicit self.pp
or by making sure that it looks like a method pp()