Setter method for Hash value

R

Rolf Pedersen

[Note: parts of this message were removed to make it a legal post.]

Hi

I guess there is a simple solution to this, but right now, I can't come up
with it.

I want to wrap two external functions to behave like a regular hash.

class MyClass
def props
some_data = SomeClass::get_prop
some_data.to_h
end
def props[key]=(value) # Not a valid construct
SomeClass::set_prop(key, value)
end
end

props["timeout"]
=>"10"

props["timeout"]="20"
=> nil


Now, the getter method works perfectly, but I don't know how to declare the
setter method :eek:(

Anyone?

Kind regards,
Rolf
 
B

botp

=A0 =A0 =A0 =A0def props[key]=3D(value) =A0 =A0 =A0 # Not a valid constru=
ct

just a crude example,


class C
def initialize
@h=3D{}
end
def [](index)
@h[index]
end
def []=3D(index,value)
@h[index]=3Dvalue
end
def h
@h
end
end
#=3D> nil
c=3DC.new
#=3D> #<C:0x8873e8c @h=3D{}>
c[:a]=3D1
#=3D> 1
c[:b]=3D2
#=3D> 2
c[:a]
#=3D> 1
c.h
#=3D> {:a=3D>1, :b=3D>2}
c
#=3D> #<C:0x8873e8c @h=3D{:a=3D>1, :b=3D>2}>

best regards -botp
 
N

Nation, Carey

Try calling it props=3D for the method name itself.

Something like

def props=3D(key, value) maybe?


-----Original Message-----
From: Rolf Pedersen [mailto:[email protected]]=20
Sent: Thursday, February 03, 2011 11:12 AM
To: ruby-talk ML
Subject: Setter method for Hash value

Hi

I guess there is a simple solution to this, but right now, I can't come
up with it.

I want to wrap two external functions to behave like a regular hash.

class MyClass
def props
some_data =3D SomeClass::get_prop
some_data.to_h
end
def props[key]=3D(value) # Not a valid construct
SomeClass::set_prop(key, value)
end
end

props["timeout"]
=3D>"10"

props["timeout"]=3D"20"
=3D> nil


Now, the getter method works perfectly, but I don't know how to declare
the setter method :eek:(

Anyone?

Kind regards,
Rolf
 
R

Rolf Pedersen

[Note: parts of this message were removed to make it a legal post.]

I see I have forgotten something when extracting code to a more generic
example: making an instance of the class...
So the corrected version:

class MyClass
def props
some_data = SomeClass::get_prop
some_data.to_h
end
def props[key]=(value) # Not a valid construct
SomeClass::set_prop(key, value)
end
end

my_instance = MyClass.new
my_instance.props["timeout"]
=>"10"

my_instance.props["timeout"]="20"
=> nil

-Rolf
 
R

Rolf Pedersen

[Note: parts of this message were removed to make it a legal post.]

Hi Brian (and others who have contributed with suggestions along the same
line)

It's not the class MyClass that I'd like to behave like a Hash.
I'm trying to make getter and setter methods for a virtual hash property
called props.
Under the hood, the implementation calls external methods to retrieve or
store the given values for a given key.

Kind regards,
-Rolf

Rolf Pedersen wrote in post #979431:
def props[key]=(value) # Not a valid construct

def []=(key,value)
props["timeout"]="20"
=> nil

foo = MyClass.new
foo["timeout"]="20"
 
B

botp

I'm trying to make getter and setter methods for a virtual hash property
called props. Under the hood, the implementation calls external methods to retrieve or
store the given values for a given key.

objects receive methods wc return objects, wc in turn can receive
another method, and so fort on the chain..

eg,

class MyClass
def props
some_data = SomeClass::get_prop
end
def []=(key,value)
SomeClass::set_prop(key, value)
end
end
#=> nil

class SomeClass
class << self
@@h={}
def get_prop
@@h
end
def set_prop key,value
@@h[key]=value
end
def show
@@h
end
end
end
#=> nil

c=MyClass.new
#=> #<MyClass:0x888f6b4>
c.props
#=> {}
c.props[:a]=1
#=> 1
c.props[:b]=2
#=> 2
c.props
#=> {:a=>1, :b=>2}
SomeClass::show
#=> {:a=>1, :b=>2}


best regards -botp
 
B

botp

sorry, ignore the previous unclear post..

try again,

class MyClass
def props
some_data = SomeClass::get_prop
self
end
def []=(key,value)
p "i was called"
SomeClass::set_prop(key, value)
end
end
#=> nil

class SomeClass
class << self
@@h={}
def get_prop
@@h
end
def set_prop key,value
@@h[key]=value
end
def show
@@h
end
end
end
#=> nil

c=MyClass.new
#=> #<MyClass:0x8887b94>
c.props
#=> #<MyClass:0x8887b94>
c.props[:a]=1
"i was called"
#=> 1
c.props[:b]=2
"i was called"
#=> 2
c.props
#=> #<MyClass:0x8887b94>
SomeClass::show
#=> {:a=>1, :b=>2}


best regards -botp
 
B

Brian Candler

Rolf Pedersen wrote in post #979464:
Hi Brian (and others who have contributed with suggestions along the
same
line)

It's not the class MyClass that I'd like to behave like a Hash.
I'm trying to make getter and setter methods for a virtual hash property
called props.

Then the 'props' object which you return needs methods [] and []=
defined, which do whatever you want them to do.

I see you are using these methods on the class itself (not instances of
the class):

SomeClass::set_prop(key, value)

In that case, you can define them as class methods:

class SomeClass
def self.[](key)
get_prop(key)
end
def self.[]=(key,value)
set_prop(key,value)
end
end

And then simply return the class itself:

class MyClass
def props
SomeClass
end
end

If you were using *instances* of SomeClass, then personally I would just
define methods [] and []= as instance methods. Depending on how
Hash-like you want this object to be, you may want to define some other
methods too.

If there is some particular reason why you can't do that, then you would
have to return a proxy object, whose [] and []= methods are relayed to
get_prop and set_prop on the underlying SomeClass object.

If you still want props to return an actual Hash, then it will have to
be a Hash which has been modified so that []= performs the operation on
the underlying object.

You can use delegate.rb, or you can explicitly delegate those methods
which you want to. Here is some code from CouchTiny which wraps a Hash:

module CouchTiny
# A class which delegates a small subset of methods to a Hash (to keep
# the space as clear as possible for accessor names)
class DelegateDoc
attr_accessor :doc

def initialize(doc = {})
@doc = doc.to_hash
end

def to_hash
@doc
end

def ==(other)
@doc == other # .to_hash is done by Hash#==
end

def to_json(*args)
@doc.to_json(*args)
end

alias :eek:rig_respond_to? :respond_to?
def respond_to?(*m)
orig_respond_to?(*m) || @doc.respond_to?(*m)
end

def [](k)
@doc[k.to_s]
end

def []=(k,v)
@doc[k.to_s] = v
end

def key?(k)
@doc.key?(k)
end

def has_key?(k)
@doc.has_key?(k)
end

def delete(k)
@doc.delete(k)
end

def merge!(h)
@doc.merge!(h)
end

def update(h)
@doc.update(h)
end

def dup
self.class.new(@doc.dup)
end

#def method_missing(m, *args, &block)
# @doc.__send__(m, *args, &block)
#end
end
end


Regards,

Brian.
 
R

Rolf Pedersen

[Note: parts of this message were removed to make it a legal post.]

Thanks for the input, botp.
Your example does the job allright, but designwise, I don't like that the
[]= method is made available for MyClass itself.
However, I'll take whatever works for now! :eek:)

Best regards,
Rolf
 
R

Rolf Pedersen

[Note: parts of this message were removed to make it a legal post.]

Hei Brian

Thanks for the answer.
I do have a solution now which works for c.props[:key] and c.props[:key] =
"value", but that solves just part of my problem.
I realize that I need to elaborate on the "requirements" a bit further.

MyClass should have a "virtual hash property", props.
I want to interact with props, like it was a regular hash, but under the
hood, it should perform calls towards the external library.

SomeClass (renamed to DataClass in code below) just represents a sample
external library with some functions getting or setting some internal data:
* get_props() # Gets all the properties, data format is not
important, could be a comma separated list. The receiver should handle the
conversion to Hash.
* get_prop(key) # Gets one value for a given key
* set_props(data) # Set all the properties. Again, data format is not
important.
* set_prop(key, value) # Set one particular property.

With MyClass I should be able to to the following:
c = MyClass.new
(1)
c.props # under the hood, this will call SomeClass::get_props() and convert
the response to a hash
=> {:a=>1, :b=>2, :c=>3}
(2)
c.props[:a] # This should make a call to SomeClass::get_prop("a")
=> 1
(3)
c.props={:a=>"a", :b=>"b", :c=>"c"} # This should make a call to e.g.
SomeClass::set_props("a", "a", "b", "b", "c", "c")
=> {:a=>"a", :b=>"b", :c=>"c"}
(4)
c.props[:d] = "d" # This should make a call to SomeClass::set_prop("d")
=> "d"
(5)
c.props # Again, make a vall to SomeClass::get_props(), to check that
new data is stored.
=> {:a=>"a", :b=>"b", :c=>"c", :d=>"d"}


Now, following your first suggestion, Brian, I came up with the following
code, where I use a DataClass which represents the external interface, and
which happens to operate on Hash data, to make it simple:

class DataClass
@@data = {:a=>1, :b=>2, :c=>3}
def self.get_props()
@@data
end
def self.get_prop(key)
@@data[key]
end
def self.set_props(data)
@@data = data
end
def self.set_prop(key, value)
@@data[key] = value
end
end

class PropsClass
def [](key)
DataClass::get_prop(key)
end
def []=(key, value)
DataClass::set_prop(key, value)
end
end

class MyClass
def initialize
@props = PropsClass.new
end
def props
@props
end
end


Now this works for (2) and (4), but not for (1) and (3).
(1) just returns
#<PropsClass:0x1418748>
and (3) returns
test_props.rb:35:in `<main>': undefined method `props=' for
#<MyClass:0x14202d8 @props=#<PropsClass:0x14202c0>> (NoMethodError)

The reason is obvious. I haven't even found a way to call get_props and
set_props.
Clearly, something is missing.
I don't have a method that redefines = in the PropsClass. (This method
cannot be redefined, right?).
And according to my requirements, c.props should not return the PropsClass
instance, but rather call and return a value from a PropsClass function,
which I assume is not possible to do either.
So, I don't understand how (if possible) to go about achieving what I
want.... Maybe this is a dead end?
:eek:(

About your other suggestion, delegates, I have to study this a bit more. I'm
still a low-level Ruby programmer :eek:)

Best regards,
Rolf


Rolf Pedersen wrote in post #979464:
Hi Brian (and others who have contributed with suggestions along the
same
line)

It's not the class MyClass that I'd like to behave like a Hash.
I'm trying to make getter and setter methods for a virtual hash property
called props.

Then the 'props' object which you return needs methods [] and []=
defined, which do whatever you want them to do.

I see you are using these methods on the class itself (not instances of
the class):

SomeClass::set_prop(key, value)

In that case, you can define them as class methods:

class SomeClass
def self.[](key)
get_prop(key)
end
def self.[]=(key,value)
set_prop(key,value)
end
end

And then simply return the class itself:

class MyClass
def props
SomeClass
end
end

If you were using *instances* of SomeClass, then personally I would just
define methods [] and []= as instance methods. Depending on how
Hash-like you want this object to be, you may want to define some other
methods too.

If there is some particular reason why you can't do that, then you would
have to return a proxy object, whose [] and []= methods are relayed to
get_prop and set_prop on the underlying SomeClass object.

If you still want props to return an actual Hash, then it will have to
be a Hash which has been modified so that []= performs the operation on
the underlying object.

You can use delegate.rb, or you can explicitly delegate those methods
which you want to. Here is some code from CouchTiny which wraps a Hash:

module CouchTiny
# A class which delegates a small subset of methods to a Hash (to keep
# the space as clear as possible for accessor names)
class DelegateDoc
attr_accessor :doc

def initialize(doc = {})
@doc = doc.to_hash
end

def to_hash
@doc
end

def ==(other)
@doc == other # .to_hash is done by Hash#==
end

def to_json(*args)
@doc.to_json(*args)
end

alias :eek:rig_respond_to? :respond_to?
def respond_to?(*m)
orig_respond_to?(*m) || @doc.respond_to?(*m)
end

def [](k)
@doc[k.to_s]
end

def []=(k,v)
@doc[k.to_s] = v
end

def key?(k)
@doc.key?(k)
end

def has_key?(k)
@doc.has_key?(k)
end

def delete(k)
@doc.delete(k)
end

def merge!(h)
@doc.merge!(h)
end

def update(h)
@doc.update(h)
end

def dup
self.class.new(@doc.dup)
end

#def method_missing(m, *args, &block)
# @doc.__send__(m, *args, &block)
#end
end
end


Regards,

Brian.
 
J

Jesús Gabriel y Galán

What about this:

class MyClass
def props
@props = DataClass::get_props()
Props.new @props
end

def props=(h)
DataClass::set_props h
end
end

class Props
def initialize h
@h = h
end

def [](key)
DataClass::get_prop key
end

def []=(key,value)
DataClass::set_prop key,value
end

def inspect; @h.inspect; end
def to_s; @h.to_s; end
end


class DataClass
@@data = {:a=>1, :b=>2, :c=>3}
def self.get_props()
@@data
end
def self.get_prop(key)
@@data[key]
end
def self.set_props(data)
@@data = data
end
def self.set_prop(key, value)
@@data[key] = value
end
end


Jesus.
 
B

Brian Candler

Rolf Pedersen wrote in post #979601:
MyClass should have a "virtual hash property", props.
I want to interact with props, like it was a regular hash, but under the
hood, it should perform calls towards the external library.

Then simply return an object with those characteristics. This is Ruby,
remember :)
With MyClass I should be able to to the following:
c = MyClass.new
(1)
c.props # under the hood, this will call SomeClass::get_props() and
convert
the response to a hash
=> {:a=>1, :b=>2, :c=>3}

So you are now saying you must return an *actual* hash at this point?
Then that is a separate object, and any mutations made will be local to
that hash.
(2)
c.props[:a] # This should make a call to SomeClass::get_prop("a")
=> 1

No it won't, if c.props returned a Hash. So your requirements (1) and
(2) are contradictory.

I suggest you go with option 2: return some object, which when you call
the [] method on that object, it in turn calls SomeClass.get_prop(xxx).
That's the "proxy" object I was talking about before.
(3)
c.props={:a=>"a", :b=>"b", :c=>"c"} # This should make a call to e.g.
SomeClass::set_props("a", "a", "b", "b", "c", "c")
=> {:a=>"a", :b=>"b", :c=>"c"}

That's easy enough. Your c object can have a props=(h) method which
iterates over h, or turns it into an Array, and calls set_props
accordingly.
(4)
c.props[:d] = "d" # This should make a call to SomeClass::set_prop("d")
=> "d"

That's a different requirement: that the object returned by c.props have
specific behaviour when its []= method is called, similar to (2).

However (3) and (4) are not contradictory. You can implement both if you
wish.
(5)
c.props # Again, make a vall to SomeClass::get_props(), to check
that
new data is stored.
=> {:a=>"a", :b=>"b", :c=>"c", :d=>"d"}

That is the same as (1), which contradicts (2).

Actually, you can have an almost-Hash, by either subclassing Hash, or by
defining singleton methods on a Hash object. Then it can be a Hash which
does magic things when you assign to it. This may or may not be good
design - I try to avoid magic if possible

h = {"foo"=>1, "bar"=>2}
def h.[]=(key,val)
puts "Hah, tricked you, you tried to set #{key} to #{val}!"
end

h
h["foo"]
h["foo"]=999

By setting an instance variable on the Hash (more magic) you can
remember which object you want to proxy []= to.
class DataClass
@@data = {:a=>1, :b=>2, :c=>3}

Try to avoid class variables. An instance variable of the class (@data)
would work just as well here. @@var has really strange semantics which I
can never entirely remember, and once you've been bitten by them, you'll
choose to use instance variables as well.

Note that an instance variable of the class is not the same as an
instance variable of an instance of that class.

Just change @@data to @data throughout.
(1) just returns
#<PropsClass:0x1418748>

Yep, it's returning that object, not a hash. You can choose between
returning an object with Hash-like properties, or an actual Hash.
and (3) returns
test_props.rb:35:in `<main>': undefined method `props=' for
#<MyClass:0x14202d8 @props=#<PropsClass:0x14202c0>> (NoMethodError)

You simply forgot to define this method. You have:

def props
@props
end

but you also need:

def props=(val)
# do stuff, e.g. @props.h.replace(val)
# except you haven't made h an accessor; I suggest
# you do, otherwise you need something ugly:
@props.instance_variable_get:)@h).replace(val)
end
I don't have a method that redefines = in the PropsClass. (This method
cannot be redefined, right?).

foo.bar = baz

is a method called "bar=", and you can define that.

B.
 
R

Rolf Pedersen

Hi Jesus

It does seem to be working. At least the example "requirements" that I
defined does give the expected response.
I have to admit, I need to study this a bit, to figure out HOW it is
working, though. ;o)

I will try to incorporate this into the actual code now, and check if it
still holds.

Thanks.

Best regards,
Rolf
 
J

Jesús Gabriel y Galán

Hi Jesus

It does seem to be working. At least the example "requirements" that I
defined does give the expected response.
I have to admit, I need to study this a bit, to figure out HOW it is
working, though. ;o)

You have two sets of requirements:

1.- Calls on the instance of MyClass: props and props=
2.- Calls on the object returned by the previous props calls: [] and []=

You need to forward these 4 calls to another class. The first two are
easy: we just implement the MyClass#props and MyClass#props= to do
what we want.

For the other two, you need a proxy object that can delegate [] and
[]= to DataClass too. For this to work, MyClass#props needs to wrap
the actual hash returned by DataClass with a wrapper object (Props).
As you need this proxy object to have some hash like behaviour, you
can implement whatever methods you need to behave like a hash. As an
example, apart from [] and []= I have implemented inspect and to_s.


Try to avoid class variables. An instance variable of the class (@data)
would work just as well here. @@var has really strange semantics which I
can never entirely remember, and once you've been bitten by them, you'll
choose to use instance variables as well.

I completely agree. I was in a rush when I wrote my previous post, so
I left it as it is. Using instance variables on the DataClass object
is cleaner:

irb(main):030:0> class DataClass
irb(main):031:1> @data = {:a=>1, :b=>2, :c=>3}
irb(main):032:1> def self.get_props()
irb(main):033:2> @data
irb(main):034:2> end
irb(main):035:1> def self.get_prop(key)
irb(main):036:2> @data[key]
irb(main):037:2> end
irb(main):038:1> def self.set_props(data)
irb(main):039:2> @data = data
irb(main):040:2> end
irb(main):041:1> def self.set_prop(key, value)
irb(main):042:2> @data[key] = value
irb(main):043:2> end
irb(main):044:1> end
=> nil
irb(main):045:0> c = MyClass.new
=> #<MyClass:0xb7881b40>
irb(main):046:0> c.props
=> {:b=>2, :a=>1, :c=>3}
irb(main):047:0> c.props = {:a => 3, :b => 0, :c => 5, :d => 6}
=> {:b=>0, :a=>3, :c=>5, :d=>6}
irb(main):048:0> c.props
=> {:b=>0, :a=>3, :c=>5, :d=>6}
irb(main):049:0> c.props[:a]
=> 3
irb(main):050:0> c.props[:a] = 55
=> 55
irb(main):051:0> c.props[:a]
=> 55
irb(main):052:0> c.props
=> {:b=>0, :a=>55, :c=>5, :d=>6}

I hope it's clearer now. Let me know if you need further help
understanding this.

Jesus.
 
R

Rolf Pedersen

Hi Jesus

2011/2/4 Jes=FAs Gabriel y Gal=E1n said:
Hi Jesus

It does seem to be working. At least the example "requirements" that I
defined does give the expected response.
I have to admit, I need to study this a bit, to figure out HOW it is
working, though. ;o)

You have two sets of requirements:

1.- Calls on the instance of MyClass: props and props=3D
2.- Calls on the object returned by the previous props calls: [] and []= =3D

You need to forward these 4 calls to another class. The first two are
easy: we just implement the MyClass#props and MyClass#props=3D to do
what we want.

For the other two, you need a proxy object that can delegate [] and
[]=3D to DataClass too. For this to work, MyClass#props needs to wrap
the actual hash returned by DataClass with a wrapper object (Props).
As you need this proxy object to have some hash like behaviour, you
can implement whatever methods you need to behave like a hash. As an
example, apart from [] and []=3D I have implemented inspect and to_s.


Try to avoid class variables. An instance variable of the class (@data)
would work just as well here. @@var has really strange semantics which = I
can never entirely remember, and once you've been bitten by them, you'l= l
choose to use instance variables as well.

I completely agree. I was in a rush when I wrote my previous post, so
I left it as it is. Using instance variables on the DataClass object
is cleaner:

irb(main):030:0> class DataClass
irb(main):031:1> @data =3D {:a=3D>1, :b=3D>2, :c=3D>3}
irb(main):032:1> def self.get_props()
irb(main):033:2> @data
irb(main):034:2> end
irb(main):035:1> def self.get_prop(key)
irb(main):036:2> @data[key]
irb(main):037:2> end
irb(main):038:1> def self.set_props(data)
irb(main):039:2> @data =3D data
irb(main):040:2> end
irb(main):041:1> def self.set_prop(key, value)
irb(main):042:2> @data[key] =3D value
irb(main):043:2> end
irb(main):044:1> end
=3D> nil
irb(main):045:0> c =3D MyClass.new
=3D> #<MyClass:0xb7881b40>
irb(main):046:0> c.props
=3D> {:b=3D>2, :a=3D>1, :c=3D>3}
irb(main):047:0> c.props =3D {:a =3D> 3, :b =3D> 0, :c =3D> 5, :d =3D> 6}
=3D> {:b=3D>0, :a=3D>3, :c=3D>5, :d=3D>6}
irb(main):048:0> c.props
=3D> {:b=3D>0, :a=3D>3, :c=3D>5, :d=3D>6}
irb(main):049:0> c.props[:a]
=3D> 3
irb(main):050:0> c.props[:a] =3D 55
=3D> 55
irb(main):051:0> c.props[:a]
=3D> 55
irb(main):052:0> c.props
=3D> {:b=3D>0, :a=3D>55, :c=3D>5, :d=3D>6}

I hope it's clearer now. Let me know if you need further help
understanding this.

Jesus.
Clear as crystal. Just what I needed! :eek:)
Appreciate all the help I got on this.

Best regards,
Rolf
 
R

Rolf Pedersen

2011/2/4 Jes=FAs Gabriel y Gal=E1n said:
For the other two, you need a proxy object that can delegate [] and
[]=3D to DataClass too. For this to work, MyClass#props needs to wrap
the actual hash returned by DataClass with a wrapper object (Props).
As you need this proxy object to have some hash like behaviour, you
can implement whatever methods you need to behave like a hash. As an
example, apart from [] and []=3D I have implemented inspect and to_s.
Instead of implementing other methods to make the wrapper object behave mor=
e
like a Hash object, why not let Props inherit Hash, and just redefine those
methods that I need to behave differently? Perhaps like this:

class Props < Hash
def initialize h
replace h
end
def [](key)
...
end
def []=3D(key, value)
...
end
end


Best regards,
-Rolf
 
J

Jesús Gabriel y Galán

2011/2/4 Jes=FAs Gabriel y Gal=E1n said:
For the other two, you need a proxy object that can delegate [] and
[]=3D to DataClass too. For this to work, MyClass#props needs to wrap
the actual hash returned by DataClass with a wrapper object (Props).
As you need this proxy object to have some hash like behaviour, you
can implement whatever methods you need to behave like a hash. As an
example, apart from [] and []=3D I have implemented inspect and to_s.
Instead of implementing other methods to make the wrapper object behave m= ore
like a Hash object, why not let Props inherit Hash, and just redefine tho= se
methods that I need to behave differently? Perhaps like this:

class Props < Hash
=A0def initialize h
=A0 =A0replace h
=A0end
=A0def [](key)
=A0 =A0...
=A0end
=A0def []=3D(key, value)
=A0 =A0...
=A0end
end

Hi,

In fact I was going to follow up the discussion with a further idea.
What I sent has a flaw, and it's the fact that the Props object gets
initialized with the hash, while ideally it should delegate also all
reads to the DataClass. It doesn't make sense to have a reference to
the resulting hash. This way, if the hash in DataClass is modified by
other means, the new values will be available to all instances of
Props (in the current implementation this might be true, because we
are returning references to the same hash, but this can be a weak
point). It's cleaner this way, in my opinion:

class MyClass
def props
Props.new
end

def props=3D(h)
DataClass::set_props h
end
end

class Props
def [](key)
DataClass::get_prop key
end

def []=3D(key,value)
DataClass::set_prop key,value
end

def inspect; DataClass::get_props.inspect; end
def to_s; DataClass::get_props.to_s; end
end


class DataClass
@data =3D {:a=3D>1, :b=3D>2, :c=3D>3}
def self.get_props()
@data
end
def self.get_prop(key)
@data[key]
end
def self.set_props(data)
@data =3D data
end
def self.set_prop(key, value)
@data[key] =3D value
end
end

As for your question about inheriting from Hash: read a bit about
Inheritance vs Composition. It's generally considered that Composition
is more flexible.

Jesus.
 

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,982
Messages
2,570,186
Members
46,739
Latest member
Clint8040

Latest Threads

Top