For the code samples going forward, keep in mind that in ruby you don't need a literal return statement to return a value from a method. Just whatever value is last, is returned:
def val
5
end
That method would always return 5.> But then if the b() call itself returns a function, then is that function auto-called as well?
No, the only way to pass a method is by using method(method_name_here), which returns a Method object. To execute a Method object, you need to call call on it:
def a
end
method(:a).call
So if you have a method that returns a method, it should not be automatically called, so there's no loop necessary: def b
method(:a)
end
z = b
Then z is a Method object, namely a.Some experiments to answer your questions (I admit I wasn't sure for all of them what the outcome would be). IRB is Ruby's repl:
irb(main):001:0> def a
irb(main):002:1> 5
irb(main):003:1> end
irb(main):019:0> {a: 1}
=> {:a=>1}
irb(main):020:0> {a(): 1}
SyntaxError: (irb):20: syntax error, unexpected ':', expecting tASSOC
irb(main):009:0> def h(num = 10)
irb(main):010:1> num
irb(main):011:1> end
irb(main):012:0> h
=> 10
irb(main):013:0> h-3
=> 7
irb(main):014:0> h -3
=> -3
irb(main):015:0> h - 3
=> 7
irb(main):001:0> a?b:c
NameError: undefined local variable or method `c' for main:ObjectBut again, it steepens the learning curve -- it's so different from other languages that it's actually kind of hard to immediately see all the implications of "well Ruby's lexer is different than C's lexer".
If you can call 0-ary functions (functions which take zero arguments) without parentheses, how does Ruby know what a statement as simple as "a = b" does? It must expand internally to something like this (in Python notation):
But then if the b() call itself returns a function, then is that function auto-called as well? So we'd have something like this as the Python translation: This can't be right.And then you get syntactic ambiguities. For example, is the Python translation of the expression x = h-3 (in Ruby) equivalent to (in Python):
(A) x = h-3
(B) x = h(-3)
(C) x = h()-3
(D) x = h()()-3
(E) x = (h-3)()
(F) x = (h()-3)()
Maybe different whitespace, different compile-time definitions, or different run-time values will change the answer! And since the talk says you can monkey-patch Ruby's integer data type, you could even presumably make integers callable so things like "x = (h()-3())()" would be possible!
And then the overloading of the colon and question mark.
Is the expression "k:v" in Ruby a dictionary containing a single key, "k", which is mapped to the value "v"? Or is it a function call of a function called "k" with a single argument, ":v"?
And the ternary operator uses colons too! "a?b:c" could translate as a function called "a?b" being called with a single argument, ":c". Or a dictionary with a key "a?b" which maps to value "c". Or of course the ternary operator! And that's assuming none of the sub-expressions involved are 0-ary functions which are automagically called!
And then what if you want to disable the automagic calling and pass a function object around? Do you have to decorate it with an initial ampersand or something every time you use it? What if you have code like this that puts either a function object or an integer into a variable:
Then you want to copy h to the variable y. If you say "y = h" then it does the wrong thing when h is a function, because then h would be auto-called. But if you use the ampersand, you do the wrong thing when h is an integer, because then you would be taking &5 and (in C notation) this would change y from being of type "int" to type "int*". Good grief!Which all reinforces my original point: Ruby syntax is aggravating! This language is impossible to deal with!
(Sorry for the double reply, but I feel like this comment is different enough from my other reply to merit its own space.)