[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

[Facets] Multiple arguments for Hash#delete

Daniel Schierbeck

8/16/2006 7:02:00 PM

This may be a Facet:

class Hash
alias_method :__delete__, :delete

def delete(*keys, &block)
if keys.length == 1
__delete__(keys.first, &block)
else
keys.map{|key| __delete__(key, &block) }
end
end
end

Probably somewhat slower, but hey, it lets you do this

a, b, c = hsh.delete :a, :b, :c

which fits in nicely with

hsh[:a, :b, :c] = 1, 2, 3

and

a, b, c = hsh[:a, :b, :c]


Cheers,
Daniel
17 Answers

Trans

8/17/2006 12:58:00 AM

0


Daniel Schierbeck wrote:
> This may be a Facet:
>
> class Hash
> alias_method :__delete__, :delete
>
> def delete(*keys, &block)
> if keys.length == 1
> __delete__(keys.first, &block)
> else
> keys.map{|key| __delete__(key, &block) }
> end
> end
> end
>
> Probably somewhat slower, but hey, it lets you do this
>
> a, b, c = hsh.delete :a, :b, :c
>
> which fits in nicely with
>
> hsh[:a, :b, :c] = 1, 2, 3
>
> and
>
> a, b, c = hsh[:a, :b, :c]

Good deal. I'll add it. Looks to be a safe override too.

Perhaps this is a good update for future version of Ruby?

T.

Daniel Schierbeck

8/17/2006 9:27:00 AM

0

Trans wrote:
> Daniel Schierbeck wrote:
>> This may be a Facet:
>>
>> class Hash
>> alias_method :__delete__, :delete
>>
>> def delete(*keys, &block)
>> if keys.length == 1
>> __delete__(keys.first, &block)
>> else
>> keys.map{|key| __delete__(key, &block) }
>> end
>> end
>> end
>>
>> Probably somewhat slower, but hey, it lets you do this
>>
>> a, b, c = hsh.delete :a, :b, :c
>>
>> which fits in nicely with
>>
>> hsh[:a, :b, :c] = 1, 2, 3
>>
>> and
>>
>> a, b, c = hsh[:a, :b, :c]
>
> Good deal. I'll add it. Looks to be a safe override too.

For once... :)

> Perhaps this is a good update for future version of Ruby?

I think the updated #[], #[]= and #delete all deserve to be in core. The
only problem I see is performance-wise, although implementing them in C
might help there.


Cheers,
Daniel

Nobuyoshi Nakada

8/17/2006 2:15:00 PM

0

Hi,

At Thu, 17 Aug 2006 04:05:08 +0900,
Daniel Schierbeck wrote in [ruby-talk:208833]:
> Probably somewhat slower, but hey, it lets you do this
>
> a, b, c = hsh.delete :a, :b, :c

What will be returned from `hsh.delete :a'?

--
Nobu Nakada

Daniel Schierbeck

8/17/2006 2:39:00 PM

0

nobu@ruby-lang.org wrote:
> Hi,
>
> At Thu, 17 Aug 2006 04:05:08 +0900,
> Daniel Schierbeck wrote in [ruby-talk:208833]:
>> Probably somewhat slower, but hey, it lets you do this
>>
>> a, b, c = hsh.delete :a, :b, :c
>
> What will be returned from `hsh.delete :a'?

The value of :a

hsh = {:a => 1, :b => 2, :c => 3}
hsh.delete :a, :b #=> [1, 2]
hsh.delete :c #=> 3

that way, you can do this

a = hsh.delete :a
b, c = hsh.delete :b, :c

Cool, right?


Cheers,
Daniel

Trans

8/17/2006 2:53:00 PM

0


Daniel Schierbeck wrote:
> nobu@ruby-lang.org wrote:
> > Hi,
> >
> > At Thu, 17 Aug 2006 04:05:08 +0900,
> > Daniel Schierbeck wrote in [ruby-talk:208833]:
> >> Probably somewhat slower, but hey, it lets you do this
> >>
> >> a, b, c = hsh.delete :a, :b, :c
> >
> > What will be returned from `hsh.delete :a'?
>
> The value of :a
>
> hsh = {:a => 1, :b => 2, :c => 3}
> hsh.delete :a, :b #=> [1, 2]
> hsh.delete :c #=> 3
>
> that way, you can do this
>
> a = hsh.delete :a
> b, c = hsh.delete :b, :c
>
> Cool, right?

Ah, Nobu has a good point. It's beeter to have same kind of output. He
also jogs my memory. Array has #delete_values_at and that's what we
need for Hash too.

def delete_values_at(*keys, &block)
keys.map{|key| delete(key, &block) }
end

Kind of long name though, maybe #delete_at would suffice?

T.

Nobuyoshi Nakada

8/17/2006 3:08:00 PM

0

Hi,

At Thu, 17 Aug 2006 23:40:18 +0900,
Daniel Schierbeck wrote in [ruby-talk:208980]:
> >> Probably somewhat slower, but hey, it lets you do this
> >>
> >> a, b, c = hsh.delete :a, :b, :c
> >
> > What will be returned from `hsh.delete :a'?
>
> The value of :a
>
> hsh = {:a => 1, :b => 2, :c => 3}
> hsh.delete :a, :b #=> [1, 2]
> hsh.delete :c #=> 3

The class of returned value varies according to the number of
arguments?

> that way, you can do this
>
> a = hsh.delete :a
> b, c = hsh.delete :b, :c

a = [:b, :c]
b = hsh.delete(*a)

might be confusing, IMHO.

--
Nobu Nakada

Daniel Schierbeck

8/17/2006 4:03:00 PM

0

nobu@ruby-lang.org wrote:
>> hsh = {:a => 1, :b => 2, :c => 3}
>> hsh.delete :a, :b #=> [1, 2]
>> hsh.delete :c #=> 3
>
> The class of returned value varies according to the number of
> arguments?

Yes. I don't see that as a big problem though, especially if there's a
second method that *always* returns an array:

hsh.delete_at :a #=> [1]
hsh.delete_at :b, :c #=> [2, 3]

It may be too much magic for some, but I think it's a very cool feature
that won't interfere with how #delete is being used at the moment.

The main reason for it becoming a Facet is that Hash#[] and Hash#[]=
also work with multiple arguments.


Cheers,
Daniel

Daniel Schierbeck

8/17/2006 4:05:00 PM

0

Trans wrote:
> Daniel Schierbeck wrote:
>> nobu@ruby-lang.org wrote:
>>> Hi,
>>>
>>> At Thu, 17 Aug 2006 04:05:08 +0900,
>>> Daniel Schierbeck wrote in [ruby-talk:208833]:
>>>> Probably somewhat slower, but hey, it lets you do this
>>>>
>>>> a, b, c = hsh.delete :a, :b, :c
>>> What will be returned from `hsh.delete :a'?
>> The value of :a
>>
>> hsh = {:a => 1, :b => 2, :c => 3}
>> hsh.delete :a, :b #=> [1, 2]
>> hsh.delete :c #=> 3
>>
>> that way, you can do this
>>
>> a = hsh.delete :a
>> b, c = hsh.delete :b, :c
>>
>> Cool, right?
>
> Ah, Nobu has a good point. It's beeter to have same kind of output. He
> also jogs my memory. Array has #delete_values_at and that's what we
> need for Hash too.
>
> def delete_values_at(*keys, &block)
> keys.map{|key| delete(key, &block) }
> end
>
> Kind of long name though, maybe #delete_at would suffice?

Read my mind... yes, I think there should be added a #delete_at method
in addition to the new #delete.


Cheers,
Daniel

Trans

8/17/2006 5:03:00 PM

0


Daniel Schierbeck wrote:

> Read my mind... yes, I think there should be added a #delete_at method
> in addition to the new #delete.

Here' is another place in which the interchangeability between Array
andHash is lacking. Array has delete_at(index), while Hash has
delete(key). These two methods should really have the same name. But
array's delete() method is delete(value), which Hash has no equivalent.
Maybe matz will be willing to do a little shuffling to improve this for
2.0, but the only choice I have in the mean time is the long winded
delete_values_at().

Also, it really doesn't work to redefine delete() as you originally
suggested b/c you'd have to use the delete_values_at to ensure you get
an expected result, otherwise you're assuming preknowledge of how many
elemets are in the Hash.

T.

Daniel Schierbeck

8/17/2006 5:22:00 PM

0

Trans wrote:
> Also, it really doesn't work to redefine delete() as you originally
> suggested b/c you'd have to use the delete_values_at to ensure you get
> an expected result, otherwise you're assuming preknowledge of how many
> elemets are in the Hash.

What do you mean? It would work fine for the purpose I've described. If
you want to be sure you get an array when deleting multiple key-value
pairs, use #delete_values_at, otherwise #delete is just fine. The nifty
thing is that it adjusts its return value according to your need.

If #delete should be altered, why should #[] and #[]= ?


Cheers,
Daniel