Hash like JS Hash (code)

G

Gavin Kistner

Although I may never use it, I thought I'd share the following
experiment. I find mildly frustrating the need to type:
myHash['foo']
to access a property of my hash, when for strings
myHash.foo
seems perfectly logical. (At least to me, coming from JavaScript.)

So I wrote the following code, which catches any methods not available
for hash and treats them like keys. (Thanks to memmove on #ruby-lang for
the idea of allowing setters in addition to getters.)



class Hash
def method_missing(meth,*args)
if /=$/=~(meth=meth.id2name) then
self[meth[0...-1]] = (args.length<2 ? args[0] : args)
else
self[meth]
end
end
end

x = { 'name'=>'Gavin', 'age'=>31 }
x.weight = 171
x.feet = ['left','right']
puts x.name , x.weight , x.foo , x.inspect

PRODUCES

Gavin
171
nil
{"name"=>"Gavin", "weight"=>171, "feet"=>["left", "right"], "age"=>31}
 
T

Tim Sutherland

Although I may never use it, I thought I'd share the following
experiment. I find mildly frustrating the need to type:
myHash['foo']
to access a property of my hash, when for strings
myHash.foo
seems perfectly logical. (At least to me, coming from JavaScript.) [...]
x = { 'name'=>'Gavin', 'age'=>31 }
x.weight = 171
x.feet = ['left','right']
puts x.name , x.weight , x.foo , x.inspect
[...]

Are you familiar with the `Struct` class?

Person = Struct.new:)name, :weight, :age, :feet)

gavin = Person.new('Gavin', 171, 31, ['left', 'right'])
gavin.name # -> 'Gavin'
gavin.weight # -> 171
gavin.age += 31 # -> 32
 
T

Tim Hunter

Although I may never use it, I thought I'd share the following
experiment. I find mildly frustrating the need to type: myHash['foo']
to access a property of my hash, when for strings myHash.foo
seems perfectly logical. (At least to me, coming from JavaScript.) [...]
x = { 'name'=>'Gavin', 'age'=>31 }
x.weight = 171
x.feet = ['left','right']
puts x.name , x.weight , x.foo , x.inspect
[...]

Are you familiar with the `Struct` class?

Person = Struct.new:)name, :weight, :age, :feet)

gavin = Person.new('Gavin', 171, 31, ['left', 'right']) gavin.name # ->
'Gavin'
gavin.weight # -> 171
gavin.age += 31 # -> 32

Also the OpenStruct class. Check out ostruct.rb.
 
C

Claude Brisson

How would you achieve the same accesses with rexml elements, to access
subelements or attributes ?

I guess it's possible, but I'm still a ruby newbie...

CloD

Tim Hunter said:
Although I may never use it, I thought I'd share the following
experiment. I find mildly frustrating the need to type: myHash['foo']
to access a property of my hash, when for strings myHash.foo
seems perfectly logical. (At least to me, coming from JavaScript.) [...]
x = { 'name'=>'Gavin', 'age'=>31 }
x.weight = 171
x.feet = ['left','right']
puts x.name , x.weight , x.foo , x.inspect
[...]

Are you familiar with the `Struct` class?

Person = Struct.new:)name, :weight, :age, :feet)

gavin = Person.new('Gavin', 171, 31, ['left', 'right']) gavin.name # ->
'Gavin'
gavin.weight # -> 171
gavin.age += 31 # -> 32

Also the OpenStruct class. Check out ostruct.rb.
 
C

Claude Brisson

(second time I try to post... I did not see my post appear on the
newslist... I hope it is not redundant, otherwise please mail me the answer)

How would you achieve the same accesses with rexml elements, to access
subelements or attributes ?

I guess it's possible, but I'm still a ruby newbie...

CloD <[email protected]>
 
G

Gavin Kistner

Claude said:
How would you achieve the same accesses with rexml elements, to access
subelements or attributes ?

I guess it's possible, but I'm still a ruby newbie...

Use the exact same code as I gave for the Hash object, but use the class
of your choice there. (To make things really ugly, do this on Object,
and EVERYTHING in Ruby will behave this way :p)

If you don't need setters, but only accessors via dot notation, it can
be simplified to:

class SomeClass
def method_missing(meth,*args)
/=$/=~meth.id2name ? nil : self[meth]
end
end


All this said, you should think hard before you do this, since it will
make your code somewhat un-ruby-like; further, you run a strong risk of
running into confusing problems, where you think you're accessing a
property by name but are in fact invoking a method.
 
G

Gavin Kistner

Claude said:
How would you achieve the same accesses with rexml elements, to access
subelements or attributes ?

I guess it's possible, but I'm still a ruby newbie...

Use the exact same code as I gave for the Hash object, but use the
class of your choice there. (To make things really ugly, do this on
Object, and EVERYTHING in Ruby will behave this way...at least,
everything that supports the [] and []= methods :p)

If you don't need setters, but only getters via dot notation, it can be
simplified to:


class SomeClass
def method_missing(meth,*args)
/=$/=~meth.id2name ? nil : self[meth]
end
end


All this said, you should think hard before you do this, since it will
make your code somewhat un-ruby-like; further, you run a strong risk of
running into confusing problems, where you think you're accessing a
property by name but are in fact invoking a method.
 
G

Gavin Kistner

Tim said:
Are you familiar with the `Struct` class?

Person = Struct.new:)name, :weight, :age, :feet)

gavin = Person.new('Gavin', 171, 31, ['left', 'right'])
gavin.name # -> 'Gavin'
gavin.weight # -> 171
gavin.age += 31 # -> 32

Of course I'm not familiar with it, otherwise why would I have made such
an un-Ruby-like hack? :) [Still, it was fun an informative to do.]

Thanks for the tip :)
 

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,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top