I have a class inheriting from Hash which has some specific methods
operating on the hash elements:
Class MyHash < Hash
def foo
...
end
End
....
Now, with Hash class, its really easy to create a new hash, eg
h = {:key1 => "val1", :key2 => "val2"}
What I would like to do is create a new instance of the class with the
same simplicity, but I'd like to avoid creating a redundant Hash and
tranferring the contents one by one to MyHash which happens if I code:
You could just extend the hash class, rather than inheriting from it. That is, instead of this:
class myHash < Hash
def foo
...
end
end
Do this:
class Hash
def foo
...
end
end
Then, all your hash objects will be given your 'foo' method and you can do things like this:
{:key => "value"}.foo
David
Neville Burnell wrote:
···
Hi,
I have a class inheriting from Hash which has some specific methods
operating on the hash elements:
Class MyHash < Hash
def foo
...
end
End
....
Now, with Hash class, its really easy to create a new hash, eg
h = {:key1 => "val1", :key2 => "val2"}
What I would like to do is create a new instance of the class with the
same simplicity, but I'd like to avoid creating a redundant Hash and
tranferring the contents one by one to MyHash which happens if I code:
h = MyHash.new(:key1 => "val1", :key2 => "val2")
and then define initialize(h={})
Whats the "ruby way" tm for something like this?
Thanks
Nev
--
David Mitchell
Software Engineer
Telogis
NOTICE:
This message (including any attachments) contains CONFIDENTIAL
INFORMATION intended for a specific individual and purpose, and
is protected by law. If you are not the intended recipient,
you should delete this message and are hereby notified that any
disclosure, copying, or distribution of this message, or the
taking of any action based on it, is strictly prohibited.
I have a class inheriting from Hash which has some specific methods
operating on the hash elements:
Class MyHash < Hash
def foo
...
end
End
....
Now, with Hash class, its really easy to create a new hash, eg
h = {:key1 => "val1", :key2 => "val2"}
What I would like to do is create a new instance of the class with the
same simplicity, but I'd like to avoid creating a redundant Hash and
tranferring the contents one by one to MyHash which happens if I code:
h = MyHash.new(:key1 => "val1", :key2 => "val2")
and then define initialize(h={})
Whats the "ruby way" tm for something like this?
irb(main):001:0> class H < Hash
irb(main):002:1> def foo; "foo"; end
irb(main):003:1> end
=> nil
irb(main):004:0> h = H[1,2,3,4]
=> {1=>2, 3=>4}
irb(main):005:0> h.class
=> H
You could just extend the hash class, rather than inheriting from it. That is, instead of this:
class myHash < Hash
def foo
...
end
end
Do this:
class Hash
def foo
...
end
end
Then, all your hash objects will be given your 'foo' method and you can do things like this:
{:key => "value"}.foo
This will work but also suffers from the usual problem with extending
core classes -- namely, it's unsafe to do unless you're sure
that your code will run in isolation.
Another possibility is to add the behavior on a per-object basis:
module MyHashStuff
def foo
# ...
end
end
h = {1,2,3,4}
h.extend(MyHashStuff)
h.foo # h now has the food method
Another option is to add a to_myhash method to Hash:
class MyHash < Hash
def foo
...
end
end
class Hash
def to_myhash
MyHash.new.update self
end
end
Now you can create myhashes like this:
{1=>2,3=>4}.to_myhash
cheers,
Mark
···
On 5/17/05, David A. Black <dblack@wobblini.net> wrote:
Hi --
On Wed, 18 May 2005, David Mitchell wrote:
> You could just extend the hash class, rather than inheriting from it. That
> is, instead of this:
>
> class myHash < Hash
> def foo
> ...
> end
> end
>
> Do this:
>
> class Hash
> def foo
> ...
> end
> end
>
> Then, all your hash objects will be given your 'foo' method and you can do
> things like this:
>
> {:key => "value"}.foo
This will work but also suffers from the usual problem with extending
core classes -- namely, it's unsafe to do unless you're sure
that your code will run in isolation.
Another possibility is to add the behavior on a per-object basis:
module MyHashStuff
def foo
# ...
end
end
h = {1,2,3,4}
h.extend(MyHashStuff)
h.foo # h now has the food method
This will work but also suffers from the usual problem with extending
core classes -- namely, it's unsafe to do unless you're sure
that your code will run in isolation.
Another possibility is to add the behavior on a per-object basis:
module MyHashStuff
def foo
# ...
end
end
h = {1,2,3,4}
h.extend(MyHashStuff)
h.foo # h now has the food method
Jet another possibility (it's a pretty rare animal, I've never seen in the wild)
is to clone a core class and alter the clone - For example, it should be straight
forward to reimplement the Set class as a clone of the Hash class.
···
---
Set = Hash.clone
class Set
# aliasing stuff is half the rent ...
alias :each , :each_key
alias :include? , :is_key?
private
# a couple of original method are be private.
alias :_implement_add, , :store
# throw out superfluous original methods
['', '=',:each_key,:each_value, :store,:is_key? ... ].each {|m| remove_method(m) }
public
# build the methods
def add(o)
_implement_add(o,true)
end
...
end
---
Note I am not advocating a rewrite of the Set class (if at all it
it should be a c-extension), it just makes a poster child example
for this idiom.
You could just extend the hash class, rather than inheriting from
it. That is, instead of this:
class myHash < Hash
def foo
...
end
end
Do this:
class Hash
def foo
...
end
end
Then, all your hash objects will be given your 'foo' method and you
can do things like this:
{:key => "value"}.foo
This will work but also suffers from the usual problem with extending
core classes -- namely, it's unsafe to do unless you're sure
that your code will run in isolation.
Another possibility is to add the behavior on a per-object basis:
module MyHashStuff
def foo
# ...
end
end
h = {1,2,3,4}
h.extend(MyHashStuff)
h.foo # h now has the food method
Another option is to add a to_myhash method to Hash:
class MyHash < Hash
def foo
...
end
end
class Hash
def to_myhash
MyHash.new.update self
end
end
Now you can create myhashes like this:
{1=>2,3=>4}.to_myhash
Note though, that this is exactly what the original poster tried to
avoid - the intermediate hash.
Another option that hasn't been mentioned yet is to use delegation. You
can have a wrapper around a hash that contains all your additional methods
and references a Hash instance.
Kind regards
robert
···
On 5/17/05, David A. Black <dblack@wobblini.net> wrote: