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
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.
Instance variables are encapsulated by using the private access modifier. Methods can be public or private, but they are usually public.
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.
They aren't always private. Usually so, but not always.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With