what is the ruby way to do this?

L

Lyndon Samson

------=_Part_3426_20661959.1132722645748
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Nice RaDD work ( Rapid Documentation Development ) !
 
J

Jeff Wood

------=_Part_3719_5383136.1132734788185
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Heh, and to think the only reason I did it was because I figured just havin=
g
the { [] } would confuse things ( badly formed hash declaration ) so I put
the goalposts in just to be sure that it saw things as a block body ...

I'll gladly take credit, I'm glad I'll be remembered for something now (
heh, need to get that into the rubyscore app )... for my "empty goalpost"
strategem ;) . I'm not Dave Thomas or DHH or _why ... or matz ... or any of
the countless others that have helped me better myself as a Rubyist, but
hopefully one day I'll get to have a big impact ... and pay them all back. =
I
thank you all everyday I get to play with Ruby.

Anyways, You could seperate them if you didn't want them to look like or ..=
 
M

Mauricio Fernández

It's not completely useless:

irb(main):001:0> noargs = proc { || 3 }
=> #<Proc:0xb7b3558c@(irb):1>
irb(main):002:0> noargs[]
=> 3
irb(main):003:0> noargs[2]
ArgumentError: wrong number of arguments (1 for 0)
from (irb):3
from (irb):3

Maybe not for long

[lambda{ }.arity, RUBY_VERSION] # => [0, "1.9.0"]

vs.

[lambda{ }.arity, RUBY_VERSION] # => [-1, "1.8.3"]
 
C

Christophe Grandsire

Selon "ako... said:
@attributes =3D {}

# Assumes the given object quacks on 'key'
def @attributes.<<( keyed_obj )
(self[keyed_obj.key]||=3D[])<<keyed_obj
end

@attributes << a1
@attributes << a2
@attributes << a3

this is something i have never seen. would you explain the 'def' line
above? is this the same as class << @attributes; def << ...; end ?

If I understand correctly you are asking whether:

def @attributes.<<(obj)
...
end

is the same as:

class << @attributes
def <<(obj)
...
end
end

(I rewrote them because the clash of << as syntax and << as method made i=
t a bit
difficult to read).

The short answer is "yes". The long asnwer is that both are ways to add a
singleton method to a particular object, @attributes in this case. The fi=
rst
one is just shorter and practical when you want to create just one single=
ton
method. But it's mostly a matter of style.
--
Christophe Grandsire.

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.
 
D

David A. Black

Hi --

David said:
Hi --

I would do

a = Hash.new { || [] }


I believe that's the first empty || I've ever seen. It's awfully
confusing (my first reaction was: *what* or an empty array? :) I'd
strongly encourage you to eschew that construct. It's deservedly
unheard of :)

It's not completely useless:

irb(main):001:0> noargs = proc { || 3 }
=> #<Proc:0xb7b3558c@(irb):1>
irb(main):002:0> noargs[]
=> 3
irb(main):003:0> noargs[2]
ArgumentError: wrong number of arguments (1 for 0)
from (irb):3
from (irb):3

Interesting. I wonder why. And it's yet another case where
proc/lambda and Proc.new are different:

noargs = Proc.new { || 3 }
=> #<Proc:0x0033654c@(irb):8>
irb(main):009:0> noargs[2]
=> 3

It seems very fragile to me as a way of communicating what's going on.
There are two ways of saying "This takes no arguments", and what they
mean depends on the Proc/proc distinction. I guess this is old news
-- it's just another twist, and one I hadn't noticed before, on that
whole area.

(Matz, please proceed with the removal of 'proc' :)


David
 
D

David A. Black

Hi --

Heh, and to think the only reason I did it was because I figured just having
the { [] } would confuse things ( badly formed hash declaration ) so I put
the goalposts in just to be sure that it saw things as a block body ...

I'll gladly take credit, I'm glad I'll be remembered for something now (
heh, need to get that into the rubyscore app )... for my "empty goalpost"
strategem ;) . I'm not Dave Thomas or DHH or _why ... or matz ... or any of
the countless others that have helped me better myself as a Rubyist, but
hopefully one day I'll get to have a big impact ... and pay them all back. I
thank you all everyday I get to play with Ruby.

Anyways, You could seperate them if you didn't want them to look like or ...
like ...

{ | | [] } ... although that's kinda ugly to me.

No argument there :)
I'd be just as happy to use the new block syntax ->{ [] } ... when is that
going to see the light of day ???

I think I'm not alone is saying: hopefully never :) Anyway, you can
just do:

Hash.new { [] }

It's a pretty common idiom, and the block is unambiguously a block.
(If it were a hash argument it would have to be in parentheses.)


David
 
D

David A. Black

Hi --

Selon "ako... said:
@attributes = {}

# Assumes the given object quacks on 'key'
def @attributes.<<( keyed_obj )
(self[keyed_obj.key]||=[])<<keyed_obj
end

@attributes << a1
@attributes << a2
@attributes << a3

this is something i have never seen. would you explain the 'def' line
above? is this the same as class << @attributes; def << ...; end ?

If I understand correctly you are asking whether:

def @attributes.<<(obj)
...
end

is the same as:

class << @attributes
def <<(obj)
...
end
end

(I rewrote them because the clash of << as syntax and << as method made it a bit
difficult to read).

The short answer is "yes". The long asnwer is that both are ways to add a
singleton method to a particular object, @attributes in this case. The first
one is just shorter and practical when you want to create just one singleton
method. But it's mostly a matter of style.

There's also a (usually not too important) difference involving the
scope of constants. The << version will see constants in the
singleton class, whereas the def obj.meth version won't:

obj = Object.new

A = 1

class << obj
A = 2
def x
puts A
end
end

def obj.y
puts A
end

obj.x # 2
obj.y # 1


David
 
R

Robert Klemme

David said:
Hi --

Heh, and to think the only reason I did it was because I figured
just having the { [] } would confuse things ( badly formed hash
declaration ) so I put the goalposts in just to be sure that it saw
things as a block body ...

I'll gladly take credit, I'm glad I'll be remembered for something
now ( heh, need to get that into the rubyscore app )... for my
"empty goalpost" strategem ;) . I'm not Dave Thomas or DHH or _why
... or matz ... or any of the countless others that have helped me
better myself as a Rubyist, but hopefully one day I'll get to have a
big impact ... and pay them all back. I thank you all everyday I get
to play with Ruby.

Anyways, You could seperate them if you didn't want them to look
like or ... like ...

{ | | [] } ... although that's kinda ugly to me.

No argument there :)
I'd be just as happy to use the new block syntax ->{ [] } ... when
is that going to see the light of day ???

I think I'm not alone is saying: hopefully never :) Anyway, you can
just do:

Hash.new { [] }

It's a pretty common idiom, and the block is unambiguously a block.
(If it were a hash argument it would have to be in parentheses.)

Note though that this idiom will most likely lead to surprising results
wrt the OP's requirement. :)

Cheers

robert
 
G

Gavin Kistner

@attributes = Hash.new {|h,k| h[k] = Array.new}

Hey, thanks for that! I had no idea that the block form of Hash
creation had block arguments. Sure it's in 'ri', but who looks there? ;)

I often see people suggesting:
Hash.new{ [] }
without realizing that this doesn't set the value on the hash, just
returns a blank array. I've never been able to use the block
constructor syntax because it was so useless (because I also didn't
know that <<= was a valid compound method).

foo = Hash.new{ [] }
foo[:bar] << 1
foo[:foo] << 2
foo[:bar] << 3
p foo
#=>{}

foo = Hash.new{ |h,v| h[v]=[] }
foo[:bar] << 1
foo[:foo] << 2
foo[:bar] << 3
p foo
#=>{:bar=>[1, 3], :foo=>[2]}

foo = Hash.new{ [] }
foo[:bar] <<= 1
foo[:foo] <<= 2
foo[:bar] <<= 3
p foo
#=>{:bar=>[1, 3], :foo=>[2]}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top