On Thu, Jan 17, 2002 at 04:23:40AM +0900, Jim Freeze wrote:
> On Thu, Jan 17, 2002 at 04:09:34AM +0900, Jim Freeze wrote:
> > On Thu, Jan 17, 2002 at 03:55:38AM +0900, Phil Tomson wrote:
> > > In article <20020116131656.A93722 / freebsdportal.com>,
> > > Jim Freeze  <jfreeze / freebsdportal.com> wrote:
> > > >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:
> > >     @entity = {'a'=>"fred"}
> > >   end
> > > 
> > >   def [](key)
> > >     @entity[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)
>     @hash[key]
>   end
> 
>   def []=(key,val)
>     @hash[key] = val
>   end
>   protected :[]=
> 
>   def initialize(a)
>     @hash = a
>   end
> end
> 
> and create the Test class:
> 
> class Test
>   attr_reader :h
> 
>   def initialize
>     @h = HashProtector.new({'a'=>"fred"})
>     @h2 = HashProtector.new({'a'=>"fred"})
>   end
> 
>   def set_h(k,v)
>     @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