[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Why can't I redefine "<<" method to allow two parameters?

Iñaki Baz Castillo

5/8/2008 12:42:00 PM

SGksIHZlcnkgZXhydGFuZ2U6CgoKY2xhc3MgTXlBcnJheSA8IEFycmF5CiAgYWxpYXMgb3JpZ2lu
YWxfYWRkIDw8CiAgZGVmIDw8KG4saykKICAgIG9yaWdpbmFsX2FkZCAiI3tufTogI3trfSIKICBl
bmQKZW5kCgpteV9hcnJheSA9IE15QXJyYXkubmV3Cj0+IFtdCgpteV9hcnJheSA8PCAoIkhlYWRl
ciIsICJWYWx1ZSIpCgpTeW50YXhFcnJvcjogY29tcGlsZSBlcnJvcgooaXJiKToyNTogc3ludGF4
IGVycm9yLCB1bmV4cGVjdGVkICcsJywgZXhwZWN0aW5nICcpJwpteV9hcnJheSA8PCAoIkhlYWRl
ciIsICJWYWx1ZSIpCiAgICAgICAgICAgICAgICAgICAgICAgICBeCgoKQW55IHJlYXNvbiBmb3Ig
dGhpcz8gSXQgc2VlbXMgdGhhdCA8PCBpcyBhIGxpdHRsZWQgImhhcmRjb2RlZCIsIGlzbid0PwoK
LS0gCknDsWFraSBCYXogQ2FzdGlsbG8KPGliY0BhbGlheC5uZXQ+Cg==

10 Answers

Jason Roelofs

5/8/2008 12:50:00 PM

0

On Thu, May 8, 2008 at 8:42 AM, I=F1aki Baz Castillo <ibc@aliax.net> wrote:
> Hi, very exrtange:
>
>
> class MyArray < Array
> alias original_add <<
> def <<(n,k)
> original_add "#{n}: #{k}"
> end
> end
>
> my_array =3D MyArray.new
> =3D> []
>
> my_array << ("Header", "Value")
>
> SyntaxError: compile error
> (irb):25: syntax error, unexpected ',', expecting ')'
> my_array << ("Header", "Value")
> ^
>
>
> Any reason for this? It seems that << is a littled "hardcoded", isn't?
>
> --
> I=F1aki Baz Castillo
> <ibc@aliax.net>
>

The << operator is a special case handled by the parser, but you can
bypass that handling by calling the method directly:

my_array.<<("Header", "Value")

which will of course look a ton better by just using a custom method:

my_array.add_stuff "Header", "Value"

Jason R.

Iñaki Baz Castillo

5/8/2008 12:57:00 PM

0

MjAwOC81LzgsIEnDsWFraSBCYXogQ2FzdGlsbG8gPGliY0BhbGlheC5uZXQ+Ogo+ICBBbnkgcmVh
c29uIGZvciB0aGlzPyBJdCBzZWVtcyB0aGF0IDw8IGlzIGEgbGl0dGxlZCAiaGFyZGNvZGVkIiwg
aXNuJ3Q/CgpTb3JyeSwgaXQgd2FzIGEgZmFpbHVyZSBvZiBtaW5lLiBJdCB3b3JrcyBvay4KCi0t
IApJw7Fha2kgQmF6IENhc3RpbGxvCjxpYmNAYWxpYXgubmV0Pgo=

Rick DeNatale

5/8/2008 12:58:00 PM

0

On Thu, May 8, 2008 at 8:42 AM, I=F1aki Baz Castillo <ibc@aliax.net> wrote:
> Hi, very exrtange:
>
>
> class MyArray < Array
> alias original_add <<
> def <<(n,k)
> original_add "#{n}: #{k}"
> end
> end
>
> my_array =3D MyArray.new
> =3D> []
>
> my_array << ("Header", "Value")
>
> SyntaxError: compile error
> (irb):25: syntax error, unexpected ',', expecting ')'
> my_array << ("Header", "Value")

The parser sees the << OPERATOR as taking a left and right argument,
and turns that into a message send to the left argument. If you want
to use additional arguments you need to be a bit more explicit and use
a little less syntactic sugar:

my_array.<<("Header","Value") # =3D> ["Header: Value"]

--=20
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Iñaki Baz Castillo

5/8/2008 1:02:00 PM

0

MjAwOC81LzgsIEnDsWFraSBCYXogQ2FzdGlsbG8gPGliY0BhbGlheC5uZXQ+Ogo+IDIwMDgvNS84
LCBJw7Fha2kgQmF6IENhc3RpbGxvIDxpYmNAYWxpYXgubmV0PjoKPgo+ID4gIEFueSByZWFzb24g
Zm9yIHRoaXM/IEl0IHNlZW1zIHRoYXQgPDwgaXMgYSBsaXR0bGVkICJoYXJkY29kZWQiLCBpc24n
dD8KPgo+Cj4gU29ycnksIGl0IHdhcyBhIGZhaWx1cmUgb2YgbWluZS4gSXQgd29ya3Mgb2suCgoK
Tm9vb29vb29vbywgaXQgZG9lc24ndCB3b3JrIE9LIGF0IGFsbCEhIQoKSXQganVzdCB3b3JrcyBp
ZiBJIGNhbGwgdG8gdGhlIHJlZGVmaW5lZCA8PCBtZXRob2Qgd2l0aCBET1QgYW5kCmFyZ3VtZW50
cyBiZXR3ZWVuICggKToKCiAgbXlfYXJyYXkuPDwoImhvbGEiLCJwZXBlIikgICAgICMgTm90ZSB0
aGUgRE9UIGluIC48PAogID0+IFsiaG9sYTogcGVwZSJdCgogIG15X2FycmF5PDwoImhvbGEiLCJw
ZXBlIikgICAgICAjIFdpdGhvdXQgRE9UCiAgU3ludGF4RXJyb3I6IGNvbXBpbGUgZXJyb3IKICAo
aXJiKToxMTogc3ludGF4IGVycm9yLCB1bmV4cGVjdGVkICcsJywgZXhwZWN0aW5nICcpJwogIG15
X2FycmF5PDwoImhvbGEiLCJwZXBlIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICBeCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbSAoaXJiKToxMQogICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb20gOjAKCldoeT8/CgotLSAKScOxYWtp
IEJheiBDYXN0aWxsbwo8aWJjQGFsaWF4Lm5ldD4K

Jens Wille

5/8/2008 1:19:00 PM

0

Jason Roelofs [2008-05-08 14:50]:
> On Thu, May 8, 2008 at 8:42 AM, Iñaki Baz Castillo <ibc@aliax.net> wrote:
>> Hi, very exrtange:
>>
>>
>> class MyArray < Array
>> alias original_add <<
>> def <<(n,k)
>> original_add "#{n}: #{k}"
>> end
>> end
>>
>> my_array = MyArray.new
>> => []
>>
>> my_array << ("Header", "Value")
>>
>> SyntaxError: compile error
>> (irb):25: syntax error, unexpected ',', expecting ')'
>> my_array << ("Header", "Value")
>> ^
>>
>>
>> Any reason for this? It seems that << is a littled "hardcoded", isn't?
>>
>> --
>> Iñaki Baz Castillo
>> <ibc@aliax.net>
>>
>
> The << operator is a special case handled by the parser, but you can
> bypass that handling by calling the method directly:
the point is that you can't call an operator with multiple
arguments. maybe something like this will suit you (note that you
don't need to alias if you inherit from Array):

class MyArray < Array
def <<(*a)
a = [*(a=*a)] # a.to_a.flatten_once ;-)
raise ArgumentError, "wrong number of arguments (#{a.size} for
2)" if a.size != 2

super a.join(': ')
end
end

my_array = MyArray.new
my_array << ['Header1', 'Value1'] # => ["Header1: Value1"]
my_array.<<('Header2', 'Value2') # => ["Header1: Value1",
"Header2: Value2"]

cheers
jens

--
Jens Wille, Dipl.-Bibl. (FH)
prometheus - Das verteilte digitale Bildarchiv für Forschung & Lehre
Kunsthistorisches Institut der Universität zu Köln
Albertus-Magnus-Platz, D-50923 Köln
Tel.: +49 (0)221 470-6668, E-Mail: jens.wille@uni-koeln.de
http://www.prometheus-bild...

Robert Klemme

5/8/2008 1:24:00 PM

0

2008/5/8 I=F1aki Baz Castillo <ibc@aliax.net>:
> 2008/5/8, I=F1aki Baz Castillo <ibc@aliax.net>:
>> 2008/5/8, I=F1aki Baz Castillo <ibc@aliax.net>:
>>
>> > Any reason for this? It seems that << is a littled "hardcoded", isn't=
?
>>
>>
>> Sorry, it was a failure of mine. It works ok.
>
>
> Nooooooooo, it doesn't work OK at all!!!
>
> It just works if I call to the redefined << method with DOT and
> arguments between ( ):
>
> my_array.<<("hola","pepe") # Note the DOT in .<<
> =3D> ["hola: pepe"]
>
> my_array<<("hola","pepe") # Without DOT
> SyntaxError: compile error
> (irb):11: syntax error, unexpected ',', expecting ')'
> my_array<<("hola","pepe")
> ^
> from (irb):11
> from :0
>
> Why??

As others have pointed out it is not an issue of method #<< but of the
syntax. In other words, the syntax allows for << just one argument to
the left and one to the right (similar to #+ and all other _binary_
operators). While you can define the method #<< to accept any number
of arguments the parser simply won't call it with more than one
argument because that is a syntax error:

15:23:08 $ ruby -ce '1 << 2'
Syntax OK
15:23:11 $ ruby -ce '1 << 2 3'
-e:1: syntax error, unexpected tINTEGER, expecting $end
15:23:14 $ ruby -ce '1 << 2,3'
-e:1: syntax error, unexpected ',', expecting $end
1 << 2,3
^
15:23:16 $

HTH

Kind regards

robert

--=20
use.inject do |as, often| as.you_can - without end

Jimmy Kofler

5/8/2008 3:18:00 PM

0

> Why can't I redefine "<<" method to allow two parameters?
> Posted by Iñaki Baz Castillo (Guest) on 08.05.2008 14:42
> Hi, very exrtange:
> ...
> my_array << ("Header", "Value")
>
>

This seems to work as well:

ruby -e 'p [1,2,3] << 4 << 5'
#=> [1, 2, 3, 4, 5]

Cheers,

j.k.
--
Posted via http://www.ruby-....

Phillip Gawlowski

5/8/2008 3:51:00 PM

0

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

David A. Black wrote:

|> ruby -e 'p [1,2,3] << 4 << 5'
|> #=> [1, 2, 3, 4, 5]
|
| What do you guys have against #push? :-)

Nothing that works. ;P

Seriously, though: I prefer it. It makes it explicit what I'm doing.

No confusion possible with, say, a HERE doc (sp?), or a bitshift operator.

- --
Phillip Gawlowski
Twitter: twitter.com/cynicalryan
Blog: http://justarubyist.bl...

~ - You know you've been hacking too long when...
...you almost get hit by a bus that pulled away from the stop without
looking and you say: PANIC: bus error
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail....

iEYEARECAAYFAkgjIWgACgkQbtAgaoJTgL8LNwCglHoCwu4F0n7zBSfKSQ+HySkm
9KEAnRRD2lzMy500iinYqwi+yPTqWMYj
=TxDg
-----END PGP SIGNATURE-----

Rick DeNatale

5/8/2008 4:07:00 PM

0

On Thu, May 8, 2008 at 10:18 AM, David A. Black <dblack@rubypal.com> wrote:
> Hi --

> On Thu, 8 May 2008, I=F1aki Baz Castillo wrote:

> > 2008/5/8, Jens Wille <jens.wille@uni-koeln.de>:
> >
> > > Jason Roelofs [2008-05-08 14:50]:
> > >
> > >
> > > > On Thu, May 8, 2008 at 8:42 AM, I=F1aki Baz Castillo <ibc@aliax.net=
>
> wrote:
> > > >
> > > the point is that you can't call an operator with multiple
> > > arguments. maybe something like this will suit you (note that you
> > > don't need to alias if you inherit from Array):
> > >
> > > class MyArray < Array
> > > def <<(*a)
> > > a =3D [*(a=3D*a)] # a.to_a.flatten_once ;-)
> > > raise ArgumentError, "wrong number of arguments (#{a.size} for
> > > 2)" if a.size !=3D 2
> > >
> > > super a.join(': ')
> > >
> > > end
> > > end
> > >
> > > my_array =3D MyArray.new
> > >
> > > my_array << ['Header1', 'Value1'] # =3D> ["Header1: Value1"]
> > > my_array.<<('Header2', 'Value2') # =3D> ["Header1: Value1",
> > > "Header2: Value2"]
> > >
> >
> >
> > Thanks to all. Finally I'll just create a "add" method that will call
> > internally to << method using appropiate syntax:
> > self.<< (k, v)
> >
>
> I would just use Array#push:
>
>
> >
> > > [1,2,3].push(4,5)
> > >
> >
> =3D> [1, 2, 3, 4, 5]

We seem to have lost track of what the OP was trying to do,

class MyArray < Array
alias original_add <<
def <<(n,k)
original_add "#{n}: #{k}"
end
end

He wants

[1,2,3].whatever_the_heck_he_decides_to_call_it(4,5) #=3D> [1,2,3, "4:5"]


--=20
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Robert Klemme

5/9/2008 6:41:00 AM

0

2008/5/8 Rick DeNatale <rick.denatale@gmail.com>:
> We seem to have lost track of what the OP was trying to do,
>
> class MyArray < Array
> alias original_add <<
> def <<(n,k)
> original_add "#{n}: #{k}"
> end
> end
>
> He wants
>
> [1,2,3].whatever_the_heck_he_decides_to_call_it(4,5) #=> [1,2,3, "4:5"]

There is always the option to work with an intermediary:

irb(main):001:0> class MyArray < Array
irb(main):002:1> ArrayAppender = Struct.new :array, :name do
irb(main):003:2* def <<(value)
irb(main):004:3> array.push "#{name}: #{value}"
irb(main):005:3> end
irb(main):006:2> end
irb(main):007:1> def <<(name)
irb(main):008:2> ArrayAppender.new self, name
irb(main):009:2> end
irb(main):010:1> end
=> nil
irb(main):011:0> a = MyArray.new
=> []
irb(main):012:0> a << 4 << 5
=> ["4: 5"]
irb(main):013:0>

Kind regards

robert

--
use.inject do |as, often| as.you_can - without end