What is the ruby way to do this?

@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 ?

Hi --

···

On Wed, 23 Nov 2005, Jeff Wood wrote:

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? :slight_smile: I'd
strongly encourage you to eschew that construct. It's deservedly
unheard of :slight_smile:

David

--
David A. Black
dblack@wobblini.net

Ken Kunz wrote:

Konstantin,

When you have a single attribute associated with a key, is it
acceptable to have it in a one-element array? If so, you could do
something like:

@attributes = {}
....
@attributes[a.key] ||=
@attributes[a.key] << a

Or, if you don't mind having empty keys return an empty array instead
of nil, you could do:

@attributes = Hash.new()
....
@attributes[a.key] << a

Cheers,
Ken

Careful with this one. When you do this:

Hash.new()

you set the default valued returned by the hash to an array. The problem is that it will always return the same array. So in the example provided above you will end up with an empty hash for @attributes.

What you really want is the default block style:
Hash.new{|hash, key| hash[key] = }

This will create a new array for each key.

It's an extremely sneaky little problem.

Regards,
Matthew

Quoting Caleb Tennis <caleb@aei-tech.com>:

You could get fancier and just call "<<" on everything, catching
exceptions and handling them for objects that don't implement
that method.

It's better to use respond_to? -- if you get a NameError, you can't
distinguish between the object itself not responding to :"<<" and
something deep in the bowels of its :"<<" implementation not
responding to :"<<".

-mental

sorry, what is 'ri'?

It's defining the << operator on the @attributes object

j.

···

On 11/22/05, ako... <akonsu@gmail.com> wrote:

> @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 ?

--
"Remember. Understand. Believe. Yield! -> http://ruby-lang.org"

Jeff Wood

i must confess i love it! probably won't use it much. but i love it.

-a

···

On Wed, 23 Nov 2005, David A. Black wrote:

Hi --

On Wed, 23 Nov 2005, Jeff Wood wrote:

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? :slight_smile: I'd
strongly encourage you to eschew that construct. It's deservedly
unheard of :slight_smile:

--

ara [dot] t [dot] howard [at] gmail [dot] com
all happiness comes from the desire for others to be happy. all misery
comes from the desire for oneself to be happy.
-- bodhicaryavatara

===============================================================================

Perhaps I'm missing something. Is there something wrong with the following?

a = Hash.new { }

irb tells me that it gets a new array each time.

···

On 11/22/05, David A. Black <dblack@wobblini.net> wrote:

On Wed, 23 Nov 2005, Jeff Wood wrote:

> 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? :slight_smile: I'd
strongly encourage you to eschew that construct. It's deservedly
unheard of :slight_smile:

--
Rob (votes with David on this one - bleah)

David A. Black wrote:

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? :slight_smile: I'd
strongly encourage you to eschew that construct. It's deservedly
unheard of :slight_smile:

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

···

On Wed, 23 Nov 2005, Jeff Wood wrote:

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Selon "ako..." <akonsu@gmail.com>:

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

···

--
Christophe Grandsire.

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.

ako... wrote:

sorry, what is 'ri'?

ri is a commend line program that may or may not have been installed with your distribution of ruby. It's a viewer for the documentation that was (hopefully) also installed with your disctribution of ruby.

If you type "ri Hash.new" it will display information on the class method Hash.new. If you were to use the form "ri Hash#keys" then you weould be requesting information about the instance method keys that may be called on a hash object.

Try it, and if you don't have it installed then someone can help you get it set up.

Regards,
Matthew

ok ...

a = Hash.new ->{ }

# new syntax :wink:

...

···

On 11/22/05, Ara.T.Howard <ara.t.howard@noaa.gov> wrote:

On Wed, 23 Nov 2005, David A. Black wrote:

> Hi --
>
> On Wed, 23 Nov 2005, Jeff Wood wrote:
>
>> 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? :slight_smile: I'd
> strongly encourage you to eschew that construct. It's deservedly
> unheard of :slight_smile:

i must confess i love it! probably won't use it much. but i love it.

-a
--

===============================================================================
> ara [dot] t [dot] howard [at] gmail [dot] com
> all happiness comes from the desire for others to be happy. all misery
> comes from the desire for oneself to be happy.
> -- bodhicaryavatara

===============================================================================

--
"Remember. Understand. Believe. Yield! -> http://ruby-lang.org"

Jeff Wood

Ara.T.Howard wrote:

···

On Wed, 23 Nov 2005, David A. Black wrote:

Hi --

On Wed, 23 Nov 2005, Jeff Wood wrote:

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? :slight_smile: I'd
strongly encourage you to eschew that construct. It's deservedly
unheard of :slight_smile:

i must confess i love it! probably won't use it much. but i love it.

I love it too, and will use it simply because David said he'd never seen it before.

James

--

http://www.ruby-doc.org - Ruby Help & Documentation
Ruby Code & Style - Ruby Code & Style: Writers wanted
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys
http://www.30secondrule.com - Building Better Tools

Hi --

···

On Wed, 23 Nov 2005, Ara.T.Howard wrote:

On Wed, 23 Nov 2005, David A. Black wrote:

Hi --

On Wed, 23 Nov 2005, Jeff Wood wrote:

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? :slight_smile: I'd
strongly encourage you to eschew that construct. It's deservedly
unheard of :slight_smile:

i must confess i love it! probably won't use it much. but i love it.

Keep it firmly in mind if there's every another obfuscated Ruby
contest.... :slight_smile:

David

--
David A. Black
dblack@wobblini.net

Yeah that is nuts...but I really like it :slight_smile:

Ryan

···

On 11/22/05, Ara.T.Howard <ara.t.howard@noaa.gov> wrote:

On Wed, 23 Nov 2005, David A. Black wrote:

> Hi --
>
> On Wed, 23 Nov 2005, Jeff Wood wrote:
>
>> 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? :slight_smile: I'd
> strongly encourage you to eschew that construct. It's deservedly
> unheard of :slight_smile:

i must confess i love it! probably won't use it much. but i love it.

It would be nice if there was a wiki page somewhere of these Uberdioms...

···

On 11/23/05, Rob Rypka <rascal1182@gmail.com> wrote:

On 11/22/05, David A. Black <dblack@wobblini.net> wrote:
> On Wed, 23 Nov 2005, Jeff Wood wrote:
>
> > 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? :slight_smile: I'd
> strongly encourage you to eschew that construct. It's deservedly
> unheard of :slight_smile:

Perhaps I'm missing something. Is there something wrong with the
following?

a = Hash.new { }

irb tells me that it gets a new array each time.

--
Rob (votes with David on this one - bleah)

--
Into RFID? www.rfidnewsupdate.com Simple, fast, news.

No that is how it works and that is basically what Jeff's code does.
He just has empty "goal-posts" in the block as well (it isn't really
an or operation.) He gets around the new array every time thing by
using self[key] <<= value, which is self[key] = self[key] << value.
The block will only be called when there is no values for the given
key, and once the above code is called, there will be a value for the
given key (the array.) It is pretty slick (I didn't even know <<=
existed.)

Ryan

···

On 11/22/05, Rob Rypka <rascal1182@gmail.com> wrote:

Perhaps I'm missing something. Is there something wrong with the following?

a = Hash.new { }

irb tells me that it gets a new array each time.

Maybe not for long

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

vs.

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

···

On Wed, Nov 23, 2005 at 01:58:01PM +0900, Joel VanderWerf wrote:

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

--
Mauricio Fernandez

Hi --

David A. Black wrote:

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? :slight_smile: I'd
strongly encourage you to eschew that construct. It's deservedly
unheard of :slight_smile:

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

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' :slight_smile:

David

···

On Wed, 23 Nov 2005, Joel VanderWerf wrote:

On Wed, 23 Nov 2005, Jeff Wood wrote:

--
David A. Black
dblack@wobblini.net

Hi --

Selon "ako..." <akonsu@gmail.com>:

@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

···

On Wed, 23 Nov 2005, Christophe Grandsire wrote:

--
David A. Black
dblack@wobblini.net