Inexplicable Argument Error

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:

./test1:18: syntax error, unexpected ',', expecting ')'
    @@myClassVar.capture=('myKey','myValue')

And here is the code that produces it:

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.

       ... doug

                                  ^

···

--
Posted via http://www.ruby-forum.com/.

What are you trying to do? If you're trying to assign capture an
array, you need square brackets, not parens.

-Dave

···

On Wed, Jun 6, 2012 at 2:33 PM, Doug Jolley <lists@ruby-forum.com> wrote:

./test1:18: syntax error, unexpected ',', expecting ')'
@@myClassVar.capture=('myKey','myValue')

--
Dave Aronson, Cleared/Remote Ruby on Rails Freelancer
(NoVa/DC/Remote); see www.DaveAronson.com, and blogs at
www.Codosaur.us, www.Dare2XL.com, www.RecruitingRants.com

Methods ending with = can usually only take one argument – as you
experienced, two arguments are not supported by the parser.

(Except for = methods, which takes two arguments, or using some ugly
tricks, which you don't want to use anyway.)

-- Matma Rex

···

2012/6/6 Doug Jolley <lists@ruby-forum.com>:

@@myClassVar.capture=('myKey','myValue')

Hi,

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.

···

--
Posted via http://www.ruby-forum.com/.

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.

     ... doug

···

--
Posted via http://www.ruby-forum.com/\.

Hi,

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.

Not necessarily. The array is only assigned to the parameter if Ruby
doesn’t find anything else to assign to.

# ruby -v: ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]
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

···

Am 08.06.2012 10:57, schrieb Jan E.:

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.)

-- Matma Rex

···

2012/6/6 Doug Jolley <lists@ruby-forum.com>:

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.

It'd be more idiomatic to rename the methods and =.

···

On Jun 6, 2012, at 13:38 , Doug Jolley wrote:

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.

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.

     ... doug

···

--
Posted via http://www.ruby-forum.com/\.

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.

···

2012/6/6 Bartosz Dziewoński <matma.rex@gmail.com>:

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.)

--
Iñaki Baz Castillo
<ibc@aliax.net>

The method is never called in your example. Instead, you assign a value to a local variable named "foo".

   def foo=(var)
     puts "foo was called with '#{var}'."
     42
   end

Assignment to local variable, method is never called:

   foo="hello"
   => "hello"

   foo
   => "hello"

Use explicit receiver to ensure we call the method:

   self.foo="hello"
   foo was called with 'hello'.
   => "hello"

Call method by using Object#send:

   send(:foo=, "hello")
   foo was called with 'hello'.
   => 42

Notice how the two ways to call the method give different results.

···

On 08.06.2012 02:14, Iñaki Baz Castillo wrote:

2012/6/6 Bartosz Dziewoński<matma.rex@gmail.com>:

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.

--
Lars Haugseth

Yes, sorry, my fault, I failed to add the self receiver in the example.

Thanks a lot.

···

2012/6/8 Lars Haugseth <ruby-talk@larshaugseth.com>:

The method is never called in your example. Instead, you assign a value to a
local variable named "foo".

def foo=(var)
puts "foo was called with '#{var}'."
42
end

--
Iñaki Baz Castillo
<ibc@aliax.net>