Noobie ... Simple Inheriting from Hash Question ..

N

Neville Burnell

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 =3D {:key1 =3D> "val1", :key2 =3D> "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 =3D MyHash.new:)key1 =3D> "val1", :key2 =3D> "val2")

and then define initialize(h=3D{})

Whats the "ruby way" tm for something like this?

Thanks

Nev







=20
 
D

David Mitchell

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 said:
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.
 
J

Joel VanderWerf

Neville said:
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?

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
 
D

David A. Black

Hi --

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


David
 
M

Mark Hubbart

Hi --
=20
On Wed, 18 May 2005, David Mitchell wrote:
=20
=20
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.
=20
Another possibility is to add the behavior on a per-object basis:
=20
module MyHashStuff
def foo
# ...
end
end
=20
h =3D {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=3D>2,3=3D>4}.to_myhash

cheers,
Mark
 
R

Robert Klemme

Mark said:
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
 
C

Christoph

David said:
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.

/Christoph
 

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,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top