Protecting a member hash 
Author Message
 Protecting a member hash

Hi:

I have a class that stores data in a hash.
I would like the user to be able to retrieve
values from the hash, but not modify it.

class Test
  attr_reader :entity
  def initialize

  end
end

t = Test.new
p t.entity   #=> {"a"=>"fred"}
t.entity['a'] = "changed"
p t.entity   #-> {"a"=>"changed"}


top protect it from being changed?

Thanks
--
Jim Freeze
Today is a fine day for Ruby programming.
www.freeze.org



Mon, 05 Jul 2004 02:21:17 GMT  
 Protecting a member hash


Quote:
>Hi:

>I have a class that stores data in a hash.
>I would like the user to be able to retrieve
>values from the hash, but not modify it.

>class Test
>  attr_reader :entity
>  def initialize

>  end
>end

>t = Test.new
>p t.entity   #=> {"a"=>"fred"}
>t.entity['a'] = "changed"
>p t.entity   #-> {"a"=>"changed"}


>top protect it from being changed?

Why not just define a '[]' method, but not a '[]=' method in your class
and don't use the attr_reader.  Like:

class Test
  def initialize
    #HasA hash:

  end

  def [](key)

  end

end

t = Test.new
p t['a']       #this will work
t['b']="Error" #this will raise an error

So basically, you're hiding the hash from the outside world.

Phil



Mon, 05 Jul 2004 02:33:02 GMT  
 Protecting a member hash
I don't understand how he was able to write to the hash with only an
attr_reader in place...what am I overlooking?

Jack

"On two occasions I have been asked [by members of Parliament], 'Pray,
Mr. Babbage, if you put into the machine wrong figures, will the right
answers come out?' I am not able rightly to apprehend the kind of
confusion of ideas that could provoke such a question. --Charles
Babbage"

Quote:
-----Original Message-----

Sent: Wednesday, January 16, 2002 1:56 PM
To: ruby-talk ML; undisclosed-recipients:
Subject: Re: Protecting a member hash



>Hi:

>I have a class that stores data in a hash.
>I would like the user to be able to retrieve
>values from the hash, but not modify it.

>class Test
>  attr_reader :entity
>  def initialize

>  end
>end

>t = Test.new
>p t.entity   #=> {"a"=>"fred"}
>t.entity['a'] = "changed"
>p t.entity   #-> {"a"=>"changed"}


>top protect it from being changed?

Why not just define a '[]' method, but not a '[]=' method in your class
and don't use the attr_reader.  Like:

class Test
  def initialize
    #HasA hash:

  end

  def [](key)

  end

end

t = Test.new
p t['a']       #this will work
t['b']="Error" #this will raise an error

So basically, you're hiding the hash from the outside world.

Phil



Mon, 05 Jul 2004 03:04:15 GMT  
 Protecting a member hash

Quote:



> >Hi:

> >I have a class that stores data in a hash.
> >I would like the user to be able to retrieve
> >values from the hash, but not modify it.

> >class Test
> >  attr_reader :entity
> >  def initialize

> >  end
> >end

> >t = Test.new
> >p t.entity   #=> {"a"=>"fred"}
> >t.entity['a'] = "changed"
> >p t.entity   #-> {"a"=>"changed"}


> >top protect it from being changed?

> Why not just define a '[]' method, but not a '[]=' method in your class
> and don't use the attr_reader.  Like:

> class Test
>   def initialize
>     #HasA hash:

>   end

>   def [](key)

>   end

> end

> t = Test.new
> p t['a']       #this will work
> t['b']="Error" #this will raise an error

> So basically, you're hiding the hash from the outside world.

Well. that would work, but the real story is that I have
multiple hashes in the class. So, the single Test#[] is
limiting. I suppose I would write a class for each hash.
Is there a cheaper way?

Jim

Quote:

> Phil

--
Jim Freeze
Today is a fine day for Ruby programming.
www.freeze.org


Mon, 05 Jul 2004 03:14:48 GMT  
 Protecting a member hash

Quote:




> > >Hi:

> > Why not just define a '[]' method, but not a '[]=' method in your class
> > and don't use the attr_reader.  Like:

> > class Test
> >   def initialize
> >     #HasA hash:

> >   end

> >   def [](key)

> >   end

> > end

> > t = Test.new
> > p t['a']       #this will work
> > t['b']="Error" #this will raise an error

> > So basically, you're hiding the hash from the outside world.

> Well. that would work, but the real story is that I have
> multiple hashes in the class. So, the single Test#[] is
> limiting. I suppose I would write a class for each hash.

Well, after thinking about this a little longer and trying
to implement it, I don't think this will work either.

Assume I have the class:

class HashProtector
  def [](key)

  end

  def []=(key,val)

  end
  protected :[]=

  def initialize(a)

  end
end

and create the Test class:

class Test
  attr_reader :h

  def initialize


  end

  def set_h(k,v)

  end
end

Then set_h will not work because Test is not
derived from HashProtecter. What I need is
some kind of friend mechanism.

--
Jim Freeze
Today is a fine day for Ruby programming.
www.freeze.org



Mon, 05 Jul 2004 03:25:26 GMT  
 Protecting a member hash

Quote:
> I don't understand how he was able to write to the hash with only an
> attr_reader in place...what am I overlooking?

attr_reader on the hash means code using the class could not replace the
hash instance itself with another hash instance.

Chris



Mon, 05 Jul 2004 03:25:34 GMT  
 Protecting a member hash
Quote:

> I don't understand how he was able to write to the hash with only an
> attr_reader in place...what am I overlooking?

The t.entity returns the hash. Once I have it in my possesion,
I can do whatever I want. :)
It's like doing:

  #t.entity[key] = val in 2 step:
  my_hash_ptr = t.entity
  my_hash_ptr[key] = val

So, I could merrily change all of its contents.
However, Ruby will complain if I try to do:

  t.entity = someting_else


it contents.

Jim

--
Jim Freeze
Today is a fine day for Ruby programming.
www.freeze.org



Mon, 05 Jul 2004 03:30:49 GMT  
 Protecting a member hash


Quote:



>> >Hi:

>> >I have a class that stores data in a hash.
>> >I would like the user to be able to retrieve
>> >values from the hash, but not modify it.

>> >class Test
>> >  attr_reader :entity
>> >  def initialize

>> >  end
>> >end

>> >t = Test.new
>> >p t.entity   #=> {"a"=>"fred"}
>> >t.entity['a'] = "changed"
>> >p t.entity   #-> {"a"=>"changed"}


>> >top protect it from being changed?

>> Why not just define a '[]' method, but not a '[]=' method in your class
>> and don't use the attr_reader.  Like:

>> class Test
>>   def initialize
>>     #HasA hash:

>>   end

>>   def [](key)

>>   end

>> end

>> t = Test.new
>> p t['a']       #this will work
>> t['b']="Error" #this will raise an error

>> So basically, you're hiding the hash from the outside world.

>Well. that would work, but the real story is that I have
>multiple hashes in the class. So, the single Test#[] is
>limiting. I suppose I would write a class for each hash.
>Is there a cheaper way?

Jim,

What exactly are you trying to accomplish?  Maybe there's a different way
to do it, perhaps with Structs or with  a hash of hashes?

Phil



Mon, 05 Jul 2004 03:47:25 GMT  
 Protecting a member hash

Quote:

> Jim,

> What exactly are you trying to accomplish?  Maybe there's a different way
> to do it, perhaps with Structs or with  a hash of hashes?

Hmmm..well, not being the XML expert, I am somewhat afraid
to detail what I am doing. :)

<ducking behind desk>
  I have built an abstract xml tree class. The class
  uses NQXML and creates a tree structure with nodes,
  attributes and data from the xml file. Comments are ignored.
  The motivation for doing this was to have
  easier access to the xml data instead of the NQXML
  notation. EG, I can write
    name = axt.entity['name']
  instead of
    name = node.children[0].entity.to_s
  Which I could never remember.
</ducking behind desk>

  As far as a solution, I think I have one that is suitable.
  However, I have not tried Structs. I have never used them.

  What I did was prevent returning a pointer to the hash.
  Instead, if the user asks for the hash, they get their own copy.
  If they ask for the value given a key, I return that value.

  class Test
    def initialize

    end
    def h(k=nil)


    end
  end

  t = Test.new
  t.h  #=> I get my own copy of the hash



  t.h(key) = 5  #=> syntax error

--
Jim Freeze
Today is a fine day for Ruby programming.
www.freeze.org



Mon, 05 Jul 2004 05:01:23 GMT  
 Protecting a member hash

Quote:





> > > >Hi:

> > > Why not just define a '[]' method, but not a '[]=' method in your class
> > > and don't use the attr_reader.  Like:

> > > class Test
> > >   def initialize
> > >     #HasA hash:

> > >   end

> > >   def [](key)

> > >   end

> > > end

> > > t = Test.new
> > > p t['a']       #this will work
> > > t['b']="Error" #this will raise an error

> > > So basically, you're hiding the hash from the outside world.

> > Well. that would work, but the real story is that I have
> > multiple hashes in the class. So, the single Test#[] is
> > limiting. I suppose I would write a class for each hash.

> Well, after thinking about this a little longer and trying
> to implement it, I don't think this will work either.

> Assume I have the class:

> class HashProtector
>   def [](key)

>   end

>   def []=(key,val)

>   end
>   protected :[]=

>   def initialize(a)

>   end
> end

> and create the Test class:

> class Test
>   attr_reader :h

>   def initialize


>   end

>   def set_h(k,v)

>   end
> end

> Then set_h will not work because Test is not
> derived from HashProtecter. What I need is
> some kind of friend mechanism.

Well you could declare []= private or protected in HashProtector.
Then access []= via send inside class test.  I'd advise commenting
why you're bypassing the protection mechanisms with set_h.

--
Alan Chen
Digikata LLC
http://digikata.com



Mon, 05 Jul 2004 05:06:50 GMT  
 Protecting a member hash

Quote:

> Well you could declare []= private or protected in HashProtector.
> Then access []= via send inside class test.  I'd advise commenting
> why you're bypassing the protection mechanisms with set_h.

Not a bad idea, but I tend to shy away from such techniques since
this may end up going away with 2.0.

--
Jim Freeze
Today is a fine day for Ruby programming.
www.freeze.org



Mon, 05 Jul 2004 05:33:16 GMT  
 
 [ 11 post ] 

 Relevant Pages 

1. Hash.new(Hash.new) doesn't use Hash.new as default value

2. C++ protected member behaviour in Ada 95

3. private and protected members

4. member by member copy???

5. obj.hash now == obj.hash after?

6. Hash compression (Hash 'consing') circa 1957

7. hash as key in hash

8. Sorting a Hash by value of integer stored in the Hash

9. Hash#index !==> Hash#indexes

10. Hash#index !==> Hash#indexes

11. Hash.new {block} / Hash#default_proc{,_set}

12. Moron hashing (rehashing hashing again)

 

 
Powered by phpBB® Forum Software