Hash like JS Hash (code)

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}

“Gavin Kistner” gavin@refinery.com wrote in message

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.)

Cool ! Also take a look at Dan Berger’s code snippet on RubyForge:

http://rubyforge.org/snippet/detail.php?type=snippet&id=1

– shanko

require ‘ostruct’
x = OpenStruct.new(‘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}

-austin

···

On Sun, 15 Feb 2004 05:14:56 +0900, Gavin Kistner wrote:

austin ziegler * austin@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2004.02.14
* 15.23.59

Also the OpenStruct class. Check out ostruct.rb.

···

On Sun, 15 Feb 2004 02:47:07 +0000, Tim Sutherland wrote:

In article <8hvXb.37945$uV3.63269@attbi_s51>, Gavin Kistner wrote:

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

(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 claude@renegat.net

“Gavin Kistner” gavin@refinery.com a écrit dans le message de
news:8hvXb.37945$uV3.63269@attbi_s51…

···

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}

Tim Sutherland wrote:

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? :slight_smile: [Still, it was fun an informative to do.]

Thanks for the tip :slight_smile:

···


(-, /\ / / //

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” cyclists@nc.rr.com a écrit dans le message de
news:pan.2004.02.15.02.53.29.298820@nc.rr.com

···

On Sun, 15 Feb 2004 02:47:07 +0000, Tim Sutherland wrote:

In article <8hvXb.37945$uV3.63269@attbi_s51>, Gavin Kistner wrote:

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.

Claude Brisson wrote:

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.

···


(-, /\ / / //

Claude Brisson wrote:

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.

···


(-, /\ / / //