ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> ruby-talk
ruby-talk
Re: encapsulation issue
by Josh Cheek other posts by this author
Nov 6 2009 6:43PM messages near this date
encapsulation issue | Re: encapsulation issue
On Fri, Nov 6, 2009 at 7:50 AM, James French <James.French@[...].com
>  wrote:

>  Hi,
> 
>  Is there any way of providing read only access to an array? (problem shown
>  by code below).
> 
>  class A
> 
>   def initialize
>     @dependencies = []
>   end
> 
>   # intended to be read only access
>   def dependencies
>     @dependencies
>   end
> 
>   def addDependency(d)
>     @dependencies << d
>     puts "adding #{d}"
>   end
>  end
> 
> 
>  a = A.new
>  a.addDependency("foo")
>  a.dependencies << "bar" # encapsulation subverted
> 
>  puts a.dependencies   # foo and bar both in array
> 
> 
>  Any suggestions appreciated,
>  James
> 
> 
Ruby is a dynamic language, as David pointed out, you can always get around
whatever someone does. I think the point isn't so much to make it impossible
for them to do something, but rather to make it clear how it was anticipated
that it would be used. If they want to go so far as to override the methods,
or perform instance_eval to get at the variable, then I'd take that as a
very deliberate effort, so due to their determination to get around your
design, I would just assume that they had a legitimate reason to do so, or
at least if it blows up, they'll have no cause to be upset with you for it.

I don't know how you are trying to use the class, that you feel the need to
return an array that cannot be altered, but you could define methods which
give this functionality without ever exposing the array itself, something
like this:


# consider defining methods to give the functionality you might want
# without exposing the guts of your class to the world
class Configuration
  def initialize()       @dependencies = []  end
  def add_dependency(d)  @dependencies << d  end

  def each_dependency
    @dependencies.each { |dep| yield dep }
  end
end

config = Configuration.new
config.add_dependency :dependency1
config.add_dependency :dependency2
config.add_dependency :dependency3

config.each_dependency do |dependency|
  puts "I am accessing #{dependency}, "        "without ever seeing the array."
end



# Of course, they can always get around whatever you have done,
# in the above, there is no way to get at @dependencies from the
# outside world, but in their code they could just add the code below
class Configuration
  attr_accessor :dependencies
end

p config.dependencies

__END__
Ruby is not about strict rigid code, or forcing people to use it
a certain way, it is dynamic. You have made your intentions clear,
at this point, if the user is not satisfied with your intentions,
then you must trust them to know what is best for their needs.
Something like this will not occur by accident, they have quite
deliberately decided that they need to break the encapsulation.
Thread:
James French
Josh Cheek
James French
Ralph Shnelvar
Gavin Sinclair
James French
Seebs
Aldric Giacomoni
David A. Black
James French
David A. Black
Tom Stuart
James French

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved