I am encountering a very strange argument error. I simplified my code
so that it focuses on the specific issue. Fortunately (or
unfortunately) the simplified code continued to produce the error. The
error that I am getting is:
class Class1
def initialize() @capture = Hash.new
end
def capture=(key,value) @capture[key]=value
end
def capture(key)
return @capture[key]
end
end
class Class2
@@myClassVar=Class1.new()
def Class2.xtol()
@@myClassVar.capture=(‘myKey’,‘myValue’)
return @@myClassVar.capture()
end
end
puts(Class2.xtol())
I’m tearing my hair out over this one; so, any help would be greatly
appreciated. Thanks.
Methods ending with = can usually
only take one argument
YIKES! I was not aware of that limitation. It certainly explains the
error message which had left me completely baffled.
I substituted an _ for the = and everything works perfectly. I won’t be
forgetting this real soon. Thanks so much.
Just so we’re clear – this is a parser limitation, not a language
one. You can (and you did) declare such a method with multiple
arguments, and that didn’t cause the error. You could even call it
with “obj.send :method=, arg1, arg2”.
However, “obj.method=(a,b)” is not interpreted as "call method= on obj with arguments a, b", but as "assign (a,b) to obj.method", and there’s no such thing as “(a,b)”. (Technically that
assign is then converted to another function call, but let’s skip
that.)
It’d be more idiomatic to rename the methods [] and []=.
I like it. It’s apparent that there are a number of ways to skin this
cat. I’m just glad that I now understand the issue. As I said, I was
tearing my hair out. Thanks to all.
However, “obj.method=(a,b)” is not interpreted as "call method= on obj with arguments a, b", but as "assign (a,b) to obj.method", and there’s no such thing as “(a,b)”. (Technically that
assign is then converted to another function call, but let’s skip
that.)
Ruby methods ending in “=” are special:
def foo=(var)
return 42
end
foo=“HELLO”
=> “HELLO”
It returns “HELLO” instead of 42. So it’s clear that the parses treats
those methods in a “different” way.
You actually can assign multiple values, if you use assignment syntax:
my_object.val = 1, 2
This will wrap 1 and 2 into an array and assign it to the single
parameter of the val= method. Not exactly what you want, but it works
just as well.
By the way, this is also the reason why = methods don’t accept multiple
parameters: The syntax would simply collide with Ruby’s multiple
assignment syntax.
Anyway, I think you shouldn’t use = methods the way you do. They are not
meant to be called directly and used as normal methods. Their only
purpose is to fake the attribute syntax of classical object oriented
languages.
irb(main):001:0> class Foo
irb(main):002:1> def foo=(val)
irb(main):003:2> p val
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> f = Foo.new
=> #Foo:0x00000002704430
irb(main):007:0> f.foo = 1, 2
[1, 2]
=> [1, 2]
irb(main):008:0> x, f.foo = 1, 2 #<----
2
=> [1, 2]
irb(main):009:0> x
=> 1
irb(main):010:0>
This way, x gets the 1 and the foo= assignment method gets the 2.
Anyway, I think you shouldn’t use = methods the way you do. They
are not meant to be called directly and used as normal methods.
Their only purpose is to fake the attribute syntax of classical
object oriented languages.
Agreed.
Valete,
Marvin
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/