Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make instance variables private in Ruby?

Is there any way to make instance variables "private"(C++ or Java definition) in ruby? In other words I want following code to result in an error.

class Base   def initialize()     @x = 10   end end  class Derived < Base   def x     @x = 20   end end  d = Derived.new 
like image 587
prasadvk Avatar asked Jan 25 '10 11:01

prasadvk


People also ask

Are instance variables private Ruby?

These are some of the characteristics of Instance variables in Ruby: Instance variable have the value nil before initialization. All instance variables are private by default. The instance variables of an object can only be accessed by the instance methods of that object.

Can you make instance variables private?

Instance variables are encapsulated by using the private access modifier. Methods can be public or private, but they are usually public.

How do instance variables work in Ruby?

In the Ruby programming language, an instance variable is a type of variable which starts with an @ symbol. An instance variable is used as part of Object-Oriented Programming (OOP) to give objects their own private space to store data. We say that objects can: Do things.

Are instance fields always private?

They aren't always private. Usually so, but not always.


2 Answers

Like most things in Ruby, instance variables aren't truly "private" and can be accessed by anyone with d.instance_variable_get :@x.

Unlike in Java/C++, though, instance variables in Ruby are always private. They are never part of the public API like methods are, since they can only be accessed with that verbose getter. So if there's any sanity in your API, you don't have to worry about someone abusing your instance variables, since they'll be using the methods instead. (Of course, if someone wants to go wild and access private methods or instance variables, there isn’t a way to stop them.)

The only concern is if someone accidentally overwrites an instance variable when they extend your class. That can be avoided by using unlikely names, perhaps calling it @base_x in your example.

like image 134
Josh Lee Avatar answered Sep 25 '22 17:09

Josh Lee


Never use instance variables directly. Only ever use accessors. You can define the reader as public and the writer private by:

class Foo   attr_reader :bar    private    attr_writer :bar end 

However, keep in mind that private and protected do not mean what you think they mean. Public methods can be called against any receiver: named, self, or implicit (x.baz, self.baz, or baz). Protected methods may only be called with a receiver of self or implicitly (self.baz, baz). Private methods may only be called with an implicit receiver (baz).

Long story short, you're approaching the problem from a non-Ruby point of view. Always use accessors instead of instance variables. Use public/protected/private to document your intent, and assume consumers of your API are responsible adults.

like image 36
Stephen Touset Avatar answered Sep 22 '22 17:09

Stephen Touset