Ralph Shnelvar wrote
[...]
> 
>>> MLK> (There is a way to call private methods from outside, but I will leave
>>> MLK> you to find it out on your own.  It's not generally a good thing, and
>>> MLK> I'm not going to hand you a dangerous tool until you understand when
>>>  not MLK> to use it.)
>>> 
>>> So ... when _can_ I use class_variable_get  ???
> 
> DM> You can use it whenever you want. When _should_ you use it?
> 
> DM> Like instance_variable_get, it's designed for metaprogramming -- 
> that is, when
> DM> you're trying to access a variable, but its name is dynamic.
> 
> DM> I'll give you an example of when instance_variable_get might be 
> used. Remember
> DM> attr_reader? (If not, look it up...)  Now, for speed, attr_reader is 
> defined
> DM> in C, but it can be defined in Ruby. Here's the obvious 'eval' 
> solution:
> 
> DM> class Module
> DM>   def attr_reader *names
> DM>     names.each do |name|
> DM>       eval "def #{name}; @#{name}; end"
> DM>     end
> DM>   end
> DM> end
> 
> DM> But there are many reasons I dislike eval. Here's the solution I'd 
> prefer:
> 
> DM> class Module
> DM>   def attr_reader *names
> DM>     names.each do |name|
> DM>       var_name = :"@#{name}"
> DM>       define_method name do
> DM>         instance_variable_get var_name
> DM>       end
> DM>     end
> DM>   end
> DM> end
> 
> So, basically, the reason that instance_variable_get is private to
> Module is that one does not wish make breaking encapsulation too easy?
> 
> I mean, it seems easy enough to break encapsulation by adding an
> accessor, right?

Wrong.  attr_accessor really doesn't break encapsulation in the 
conventional sense -- that is, it's not even remotely equivalent to 
declaring a public data member in C++ or Java.  Ruby has *no way* to 
make instance variables public.  This is a Good Thing.

attr_accessor just defines getter and setter methods -- and keeps the 
variable encapsulated.  When you do
@p = Person.new
@p.name = 'Ralph'
puts @p.name

the caller is making no assumptions at all about whether @p has an 
instance variable called @name.  It is impossible to tell from the code 
supplied -- that detail is completely encapsulated.  We assume that @p 
has methods called :name and :name= , but that leaks nothing of @p's 
internals.

Best,
--
Marnen Laibow-Koser
http://www.marnen.org
marnen / marnen.org
> 
> DM> I don't expect you to follow every detail here. The use of 
> define_method is an
> DM> advanced topic already. Hopefully, though, the fact that you already 
> know how
> DM> to use attr_reader should give you an idea of how that works.
> 
> DM> Also, I don't really expect you to need any of this yet -- 
> attr_reader,
> DM> attr_writer, and attr_accessor should already do everything you 
> need.
> 
> This is, actually, very lucid.  I had few problems following any of it.
> 
> Also ... I _did_ try (successfully, I hope) to follow every detail.
> 
> Many many thanks.

-- 
Posted via http://www.ruby-forum.com/.