Large subject.
Could you tell me why the NoMethodError is happening? I’m using Ruby
2.1.2
in Ubuntu 14.04.
Thanks in advance!
2.1.2 :020 > A = ‘A’
=> “A”
2.1.2 :021 > B = ‘B’
=> “B”
2.1.2 :022 > ‘A’ + ‘B’
=> “AB”
2.1.2 :023 > ‘A’ +‘B’
=> “AB”
2.1.2 :024 > A + B
=> “AB”
2.1.2 :025 > A +B
NoMethodError: undefined method [email protected]' for "B":String from (irb):25 from /home/juanjo/.rvm/rubies/ruby-2.1.2/bin/irb:11:in
’
2.1.2 :026 > A +‘B’
NoMethodError: undefined method [email protected]' for "B":String from (irb):26 from /home/juanjo/.rvm/rubies/ruby-2.1.2/bin/irb:11:in
’
2.1.2 :027 > ‘A’ +B
=> “AB”
2.1.2 :028 > a = ‘a’
=> “a”
2.1.2 :029 > a +‘B’
=> “aB”
Greets!
On Jul 19, 2014, at 17:02, Juanjo C. [email protected] wrote:
2.1.2 :025 > A +B
NoMethodError: undefined method [email protected]' for "B":String from (irb):25 from /home/juanjo/.rvm/rubies/ruby-2.1.2/bin/irb:11:in
’
RubyParser.new.parse “A + B”
=> s(:call, s(:const, :A), :+, s(:const, :B))
RubyParser.new.parse “A +B”
=> s(:call, nil, :A, s(:call, s(:const, :B), :[email protected]))
So it is seeing “A(+B)” where “+” is a unary method, much like “-”.
Same as if you typed N +4
, it’d see N(+4)
, call unary + on 4, then
pass that as an arg to N.
Right, thanks. But why that is not happening with a +“B”?
2014-07-19 22:45 GMT-03:00 Ryan D. [email protected]:
On Jul 19, 2014, at 18:50, Juanjo C. [email protected] wrote:
Right, thanks. But why that is not happening with a +“B”?
Because you’ve already taught the interpreter that ‘a’ is a local
variable, so it knows it isn’t a(+"B")
, but a + "B"
:
pp RubyParser.new.parse “a = ‘a’; a +B”
s(:block,
s(:lasgn, :a, s(:str, “a”)),
s(:call, s(:lvar, :a), :+, s(:const, :B)))
I got it!
A can’t be a method, because it’s upcase!
2014-07-19 23:10 GMT-03:00 Ryan D. [email protected]:
Dear Juanjo C.,
def UPCASEMETHODISNOTAPROBLEM(arg)
puts arg
end
UPCASEMETHODISNOTAPROBLEM “although not recommended”
Abinoam Jr.
You’re right.
2014-07-20 23:46 GMT-03:00 Abinoam Jr. [email protected]:
On 21 July 2014 12:09, Juanjo C. [email protected] wrote:
I got it!
A can’t be a method, because it’s upcase!
Note quite, upcase methods are allowed; see:
http://www.ruby-doc.org/core-2.1.2/Kernel.html#method-i-Integer Try
running: Integer -4.2
Consider this code:
a + 1
# we've never seen 'a =' before, so we assume it's a function
# first call a(), then on the resulting object call .+(1)
# same as: a().+(1)
a +1
# <word> <space> <plus> <any> = function call
# same as: a([email protected]())
C + 1
# C starts with a capital, so we assume it's a const
# same as: C.+(1)
C +1
# <word> <space> <plus> <any> = function call
# same as: C([email protected]())
b = 2
b + 1
# we *have* seen 'b =' before, so we know it's an lvar
# same as: b.+(1)
b +1
# <lvar> <space> <plus> <any> = *not* function call
# same as "b + 1": b.+(1)
You could do a similar thing with @x, @@y, or $z. Those are
unambiguously
variable names, so they’d never be interpreted as a function.
Have a think about what’s going on here, if it helps:
irb(main):001:0> def a(*args) p [:a, *args]; end
irb(main):002:0> def b(*args) p [:b, *args]; end
irb(main):003:0> def C(*args) p [:C, *args]; end
irb(main):004:0> b = 1
irb(main):005:0> C = 99
irb(main):006:0> a +1
[:a, 1]
=> [:a, 1] # a([email protected]())
irb(main):007:0> b +1
=> 2 # b.+(1)
irb(main):008:0> C +1
[:C, 1]
=> [:C, 1] # C([email protected])
irb(main):009:0> a + 1
[:a]
TypeError: no implicit conversion of Fixnum into Array
from (irb):9:in +' from (irb):9 from /usr/local/bin/irb-trunk:11:in
’
a().+(1)
irb(main):010:0> b + 1
=> 2 # b.+(1)
irb(main):011:0> C + 1
=> 100 # C.+(1)
Ok… can I say that a method in upercase with no arguements can’t be
called?
2.1.2 :010 > def Aja(*args)
2.1.2 :011?> puts ‘aja’
2.1.2 :012?> end
=> :Aja
2.1.2 :013 > Aja
NameError: uninitialized constant Aja
from (irb):13
from /home/juanjo/.rvm/rubies/ruby-2.1.2/bin/irb:11:in `’
2.1.2 :014 > Aja 1
aja
=> nil
2014-07-20 23:46 GMT-03:00 Abinoam Jr. [email protected]:
On 21 July 2014 13:20, Juanjo C. [email protected] wrote:
from /home/juanjo/.rvm/rubies/ruby-2.1.2/bin/irb:11:in `<main>'
2.1.2 :014 > Aja 1
aja
=> nil
You can add parentheses:
irb(main):001:0> def Aja *args
irb(main):002:1> puts ‘aja’
irb(main):003:1> end
=> :Aja
irb(main):004:0> Aja()
aja
=> nil
But generally speaking, yes, you need the arguments list to tell the
parser
that it’s a function call.
This email is really clear. Thanks!
2014-07-20 23:56 GMT-03:00 Matthew K. [email protected]: