[lnkForumImage]
TotalShareware - Download Free Software

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


 

Matt Maycock

10/20/2004 2:04:00 PM

So, unless you count merge! and update, there doesn't seem to be a way
to shove stuff into a hash and get the resulting updated hash back.
Now, I know merge and update make it real easy:

h = {}
h.update(:a => :b).update(:c => :d).update(:e => :f)

but this some how feels unnatural to me. maybe the following is
better for me and others?

---code---
require 'ext/singleton_class'

class Hash
def <<(k)
if @shift_value.nil? then
@shift_value = Object.new.singleton_def(:key) {k}
else
key, @shift_value = @shift_value.key, nil
self[key] = k
end
self
end
end
---end code---

---usage---
h = {}
h << :language << :ruby << :creator << :matz << :users << :"comp.lang.ruby"
p h
---result---
{:language=>:ruby, :creator=>:matz, :users=>:"comp.lang.ruby"}
-------------

Just a question of flavour, really.

--
There's no word in the English language for what you do to a dead
thing to make it stop chasing you.


10 Answers

James Gray

10/20/2004 2:18:00 PM

0

On Oct 20, 2004, at 9:04 AM, Matt Maycock wrote:

> So, unless you count merge! and update, there doesn't seem to be a way
> to shove stuff into a hash and get the resulting updated hash back.
> Now, I know merge and update make it real easy:
>
> h = {}
> h.update(:a => :b).update(:c => :d).update(:e => :f)

Why use this over:

h.update(:a => :b, :c => :d, :e => :f)

?

James Edward Gray II



Matt Maycock

10/20/2004 2:22:00 PM

0

I really just wanted to show the chaining thing - but there may be
other methods in between that give issues with doing it all at once.

~Me!


On Wed, 20 Oct 2004 23:17:35 +0900, James Edward Gray II
<james@grayproductions.net> wrote:
> On Oct 20, 2004, at 9:04 AM, Matt Maycock wrote:
>
> > So, unless you count merge! and update, there doesn't seem to be a way
> > to shove stuff into a hash and get the resulting updated hash back.
> > Now, I know merge and update make it real easy:
> >
> > h = {}
> > h.update(:a => :b).update(:c => :d).update(:e => :f)
>
> Why use this over:
>
> h.update(:a => :b, :c => :d, :e => :f)
>
> ?
>
> James Edward Gray II
>
>


--
There's no word in the English language for what you do to a dead
thing to make it stop chasing you.


Matt Maycock

10/20/2004 2:26:00 PM

0

[double post]

of course, mine isn't much better if you're doing

hash.update(...).foo.meow.update(...)

as opposed to

((hash << ... <<).foo.meow << ...)...

so maybe it is a bad idea... :-)

My main use is in cases with:
a = enum.inject(Hash.new) {|h, f|
h.update(k(f) => v(f))
}

for some odd reason,
a = enum.inject(Hash.new) {|h, f|
h << k(f) << v(f)
}
just `feels' better to me.


On Wed, 20 Oct 2004 10:22:10 -0400, Matt Maycock <ummaycoc@gmail.com> wrote:
> I really just wanted to show the chaining thing - but there may be
> other methods in between that give issues with doing it all at once.
>
> ~Me!
>
>
>
>
> On Wed, 20 Oct 2004 23:17:35 +0900, James Edward Gray II
> <james@grayproductions.net> wrote:
> > On Oct 20, 2004, at 9:04 AM, Matt Maycock wrote:
> >
> > > So, unless you count merge! and update, there doesn't seem to be a way
> > > to shove stuff into a hash and get the resulting updated hash back.
> > > Now, I know merge and update make it real easy:
> > >
> > > h = {}
> > > h.update(:a => :b).update(:c => :d).update(:e => :f)
> >
> > Why use this over:
> >
> > h.update(:a => :b, :c => :d, :e => :f)
> >
> > ?
> >
> > James Edward Gray II
> >
> >
>
> --
> There's no word in the English language for what you do to a dead
> thing to make it stop chasing you.
>


--
There's no word in the English language for what you do to a dead
thing to make it stop chasing you.


Brian Candler

10/20/2004 2:32:00 PM

0

| ---usage---
| h = {}
| h << :language << :ruby << :creator << :matz << :users << :"comp.lang.ruby"
| p h
| ---result---
| {:language=>:ruby, :creator=>:matz, :users=>:"comp.lang.ruby"}
| -------------

Ugh. Toggling internal state like that will leave you in mutex hell if
you're trying to write thread-safe code.

I suppose I wouldn't object to:

class Hash
def <<(kv)
self[kv[0]] = kv[1]
self
end
end

h << [:language,:ruby] << [:creator,:matz] << [:users,:"comp.lang.ruby"]

but I've never felt the need.

Regards,

Brian.


Robert Klemme

10/20/2004 2:33:00 PM

0


"Matt Maycock" <ummaycoc@gmail.com> schrieb im Newsbeitrag
news:e86cebfb04102007046b2c189c@mail.gmail.com...
> So, unless you count merge! and update, there doesn't seem to be a way
> to shove stuff into a hash and get the resulting updated hash back.
> Now, I know merge and update make it real easy:
>
> h = {}
> h.update(:a => :b).update(:c => :d).update(:e => :f)
>
> but this some how feels unnatural to me. maybe the following is
> better for me and others?
>
> ---code---
> require 'ext/singleton_class'
>
> class Hash
> def <<(k)
> if @shift_value.nil? then
> @shift_value = Object.new.singleton_def(:key) {k}
> else
> key, @shift_value = @shift_value.key, nil
> self[key] = k
> end
> self
> end
> end
> ---end code---
>
> ---usage---
> h = {}
> h << :language << :ruby << :creator << :matz << :users <<
:"comp.lang.ruby"
> p h
> ---result---
> {:language=>:ruby, :creator=>:matz, :users=>:"comp.lang.ruby"}
> -------------
>
> Just a question of flavour, really.

I don't like this solution because you have to store state in the Hash
that is solely connected to the appending. That's bad because this state
solely belongs to the operation, not to the Hash. This will have
surprising effects:

h = {}
h << :key1 << :val1 << :key2 # forgot :val2
# many lines later
h << :key3 << :val3

Also, as James wrote already, you can use update with multiple pairs.

If you want to have << then I'd do any of the following:

Opt 1:

class Hash
def <<(pair)
self[ pair[0] ]= pair[1]
self
end
end

h = {}
h << [:key, :val] << [:key2, :val2]


Opt 2.

class HashAdder < Struct.new(:hash, :key)
def <<(val)
self.hash[ self.key ] = val
self.hash
end
end

class Hash
def <<(key) HashAdder.new( self, key ) end
end

h = {}
h << :key << :val << :key2 << :val2


Opt 3:

Like opt 2 but reuse a single HashAdder instance toggling between key and
value much like you suggested in your post.

However, these options are far worse than simply using Hash.update(:key1
=> :val1, :key2 => :val2).

Regards

robert

Brian Candler

10/20/2004 2:35:00 PM

0

> for some odd reason,
> a = enum.inject(Hash.new) {|h, f|
> h << k(f) << v(f)
> }
> just `feels' better to me.

Feels better than

h[k(f)] = v(f)

?


Matt Maycock

10/20/2004 3:01:00 PM

0

You'd have to make that
a = enum.inject(Hash.new) {|h, f|
h[k(f)] = v(f)
h
}
-- my general desire is to have code be a single expression when I
write code. just the way I work :-)

~Me!


On Wed, 20 Oct 2004 23:35:25 +0900, Brian Candler <b.candler@pobox.com> wrote:
> > for some odd reason,
> > a = enum.inject(Hash.new) {|h, f|
> > h << k(f) << v(f)
> > }
> > just `feels' better to me.
>
> Feels better than
>
> h[k(f)] = v(f)
>
> ?
>
>


--
There's no word in the English language for what you do to a dead
thing to make it stop chasing you.


Florian Gross

10/20/2004 7:37:00 PM

0

Matt Maycock wrote:

> So, unless you count merge! and update, there doesn't seem to be a way
> to shove stuff into a hash and get the resulting updated hash back.

I'm not sure, but maybe KeyedList could help here. It is a Hash that has
list-style insert operations:

> Struct.new("Hero", :name, :reason)
>
> # Create a KeyedList which will be keyed by the names
> # of its heroic elements.
> list = KeyedList.new { |hero| hero.name }
> # Adds elements to the KeyedList.
> list << Struct::Hero.new("Yukihiro Matsumoto", "Ruby")
> list << Struct::Hero.new("Larry Wall", "Enhanced regular expressions")
> list << Struct::Hero.new("Randal Schwartz", "Schwartzian transform")
>
> list.size # => 3
> list["Yukihiro Matsumoto"].reason # => "Ruby"

It is both available as a Gem and from RPA.

Regards,
Florian Gross

Markus

10/25/2004 4:47:00 AM

0

I know I'm late to the party here, but would you be happy with:

class Hash
alias << update
end

with which you could write:

h << {:a => :b} << {:c => :d} << {:e => :f}

-- Markus

P.S. I still maintain the canonical refutation of your sig is "hug."


On Wed, 2004-10-20 at 07:04, Matt Maycock wrote:
> So, unless you count merge! and update, there doesn't seem to be a way
> to shove stuff into a hash and get the resulting updated hash back.
> Now, I know merge and update make it real easy:
>
> h = {}
> h.update(:a => :b).update(:c => :d).update(:e => :f)
>
> but this some how feels unnatural to me. maybe the following is
> better for me and others?
>
> ---code---
> require 'ext/singleton_class'
>
> class Hash
> def <<(k)
> if @shift_value.nil? then
> @shift_value = Object.new.singleton_def(:key) {k}
> else
> key, @shift_value = @shift_value.key, nil
> self[key] = k
> end
> self
> end
> end
> ---end code---
>
> ---usage---
> h = {}
> h << :language << :ruby << :creator << :matz << :users << :"comp.lang.ruby"
> p h
> ---result---
> {:language=>:ruby, :creator=>:matz, :users=>:"comp.lang.ruby"}
> -------------
>
> Just a question of flavour, really.



Matt Maycock

10/25/2004 2:54:00 PM

0

> P.S. I still maintain the canonical refutation of your sig is "hug."

The undead would still be chasing you - just with a mixed drink... :-)

--
There's no word in the English language for what you do to a dead
thing to make it stop chasing you.