From: Robert Klemme Date: 2013-04-07T07:40:19+09:00 Subject: Re: Why call of custom method doesn't work? --20cf300fb05d52c66c04d9b8e322 Content-Type: text/plain; charset=ISO-8859-1 On Fri, Apr 5, 2013 at 10:32 PM, Wins Lin wrote: > I have a code: > > module Foo > class Config > attr_reader :config > > def initialize > @config = {} <-- standard hash > end > > def <<(key, val) <-- I want to implement "<<" sign as a method > name > That does not work. You can only pass in one value (see below). For your use case better implement []= operator. > n_hash = {key => val} > if (@config.merge!(n_hash)) > return true > else > return false > end > That's quite a complicated way to convert a boolean (result of #merge!) into a boolean. The whole if else end construction is superfluous. And it won't work, too, because Hash#merge! always returns self. irb(main):001:0> h={} => {} irb(main):002:0> h.merge! 1=>2 => {1=>2} irb(main):003:0> h.merge! 1=>2 => {1=>2} irb(main):004:0> h.merge!({}) => {1=>2} > end > > end > end > > > > Now I call it: > > c = Foo::Config.new > > c << "name", "value" <- This doesn't work. ...syntax error, unexpected > ',', expecting ')' > > c.<<("name", "value") <- this works. But it's ridiculous such a call in > Ruby. > > Why > c << "name", "value" > doesn't work? Because << is a binary operator: arg1 op arg2 - that's the way code is parsed, i.e. it's defined in the syntax. With the parentheses you made it an explicit method call, which works. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/ --20cf300fb05d52c66c04d9b8e322 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable



On Fri, Apr 5, 2013 at 10:32 PM, Wins Lin <lists@ruby-forum.com= > wrote:
I have a code:

module Foo
=A0 class Config
=A0 =A0 attr_reader :config

=A0 =A0 def initialize
=A0 =A0 =A0 @config =3D {} =A0<-- standard hash
=A0 =A0 end

=A0 =A0 def <<(key, val) =A0 <-- I want to implement "<<= ;" sign as a method
name

That does not work. =A0You c= an only pass in one value (see below).

For your use case better implement []=3D operator.
=A0
=A0 =A0 =A0 n_hash =3D {key =3D> val}
=A0 =A0 =A0 if (@config.merge!(n_hash))
=A0 =A0 =A0 =A0 return true
=A0 =A0 =A0 else
=A0 =A0 =A0 =A0 return false
=A0 =A0 =A0 end

That's quite = a complicated way to convert a boolean (result of #merge!) into a boolean. = =A0The whole if else end construction is superfluous. =A0And it won't w= ork, too, because Hash#merge! always returns self.

irb(main):001:0> h=3D{}
= =3D> {}
irb(main):002:0> h.merge! 1=3D>2
=3D&g= t; {1=3D>2}
irb(main):003:0> h.merge! 1=3D>2
= =3D> {1=3D>2}
irb(main):004:0> h.merge!({})
=3D> {1=3D>2}

=A0
=A0 =A0 end

=A0 end
end



Now I call it:

c =3D Foo::Config.new

c << "name", "value" =A0 <- This doesn't w= ork. ...syntax error, unexpected
',', expecting ')'

c.<<("name", "value") =A0<- this works. But it= 's ridiculous such a call in
Ruby.

Why
c << "name", "value"
doesn't work?

Because << is a binary operator: = arg1 op arg2 - that's the way code is parsed, i.e. it's defined in = the syntax. =A0With the parentheses you made it an explicit method call, wh= ich works.

Kind regards

robert

--
remember.guy do |as, often| = as.you_can - without end
= http://blog.rubybestpractices.com/
--20cf300fb05d52c66c04d9b8e322--