Object-Oriented Programming

Hey guys, i’m trying to make a class in Ruby and I was wondering if it’s
possible to create public and private instance variables.

-Thanks

Hey Mike-

You can only declare methods private, not variables, and even then, it’s
just a suggestion:

class A
private
def foo
“bar”
end
end

a = A.new
a.send(:foo) #=> “bar”

-Steve

Mike Chao wrote in post #996303:

Hey guys, i’m trying to make a class in Ruby and I was wondering if it’s
possible to create public and private instance variables.

-Thanks

Instance variables are private by default. If you define an accessor
method, e.g. using attr_accessor, attr_reader, or attr_writer, or
writing the same method(s) by hand, then the specified instance variable
becomes public:

class Dog
attr_accessor :name

def initialize(name)
@name = name
end
end

d = Dog.new(‘George’)
puts d.name
d.name = (‘Sally’)
puts d.name

–output:–
George
Sally

In this case, attr_accessor defines two methods called name() and
name=().

On Tue, May 3, 2011 at 1:45 AM, 7stud – [email protected] wrote:

Instance methods are private by default. If you define an accessor
method, then they become public-like:

I think you meant to say “instance variables”, not “methods”.

On 05/03/11 11:13, Adam P. wrote:

On Tue, May 3, 2011 at 1:45 AM, 7stud –[email protected] wrote:

Instance methods are private by default. If you define an accessor
method, then they become public-like:
I think you meant to say “instance variables”, not “methods”.

and instance variables are available to all subclasses, also
when the class is re-opened… so “protected”, not private.

Awesome guys, thanks for the help.

On Mon, May 2, 2011 at 8:15 PM, Clifford H. [email protected]
wrote:

when the class is re-opened… so “protected”, not private.
The instance variables of an object are not available outside of the
instance (well, except via intrusive methods like
#instance_variable_set), so Ruby instance variables are more like
private data variables than protected ones. Sure, instances of
subclasses of the objects class and other members of the same class as
an object are likely to have instance variables of the same names (or,
maybe not, as instance variables can be dynamically created and
destroyed), but that doesn’t really reflect anything about the
visibility of the instance variables of the particular object.

On Tue, May 3, 2011 at 3:50 AM, Clifford H. [email protected]
wrote:

method, then they become public-like:
Correct.

so Ruby instance variables are more like
private data variables than protected ones.

Incorrect. Protected means unavailable outside this class, except to
subclasses. What definition of “protected” are you using?

In Java, protected means available to:

  1. methods (class [static] or instance) of this class and objects of
    this class
  2. methods (class [static] or instance) of subclasses of this class
    and objects of those subclasses
  3. methods (class [static] or instance) of classes defined in the same
    package as this class, and objects of those classes

In Java private means available to:
methods (class [static] or instance) of this class and objects of this
class

In C++, protected means available to:
members and friends of the base class in which the protected member is
defined, and members and friends of any classes derived from that base
class.

In C++, private means availabe to:
members and friends of the base class in which the protected member is
defined.

In Ruby, an instance variable can be directly accessed from:
methods of the object in which it exists, regardless of on which class
or module those methods are defined.

This is far more restrictive than protected access in Java and C++,
and simultaneous more restrictive (does not allow methods on other
objects – including objects of the same class and the object which is
the class – to access instance variables of an object) and less
restrictive (allows instance methods on the same object to access
instance variables of the object even when those methods were not
defined in the same class/module.)

I stand by the characterization that access to Ruby instance variables
is more like private access than protected access; in fact, its
pretty much identical to private access for methods in Ruby, which
differs from languages like Java and C++ in that private access
restricts based on the specific object, not the class. Its certainly
unlike Ruby protected access, which allows access to members from
members of other instances of subclasses of the class of which the
object is a class.

On 05/03/11 13:35, Christopher D. wrote:

#instance_variable_set),
Correct.

so Ruby instance variables are more like
private data variables than protected ones.

Incorrect. Protected means unavailable outside this class, except to
subclasses.
What definition of “protected” are you using?

Sure, instances of
subclasses of the objects class and other members of the same class as
an object are likely to have instance variables of the same names (or,
maybe not, as instance variables can be dynamically created and
destroyed), but that doesn’t really reflect anything about the
visibility of the instance variables of the particular object.

No. If I set @foo, and a subclass also does, it’s the same @foo,
in Ruby, at least. What language are you talking about?

Clifford H…

On 05/04/11 01:09, Christopher D. wrote:

In Java, protected means available to:
3. methods (class [static] or instance) of classes defined in the same
package as this class, and objects of those classes

Yes, this is where it differs from C++.

In C++, protected means available to:
members and friends

Ok, but “friends don’t let friends use friends” :slight_smile:
At least, they were basically banned in all the C++ I worked on.

In Ruby, an instance variable can be directly accessed from:
methods of the object in which it exists, regardless of on which class
or module those methods are defined.

This is far more restrictive than protected access in Java and C++,

I don’t agree, I think it’s less restrictive, but it doesn’t
matter much what we call it, as long as the semantics are clear,
and you’ve made them clear for anyone following this.

I stand by the characterization that access to Ruby instance variables
is more like private access than protected access

Well, you say tom-a-to, I say tom-ah-to, as long as we know
what we mean.

Christopher D. wrote in post #996426:

Protected means unavailable outside this class, except to
subclasses. What definition of “protected” are you using?

In Java, protected means available to:

In C++, protected means available to:

And of course, Ruby has it’s own definition of “protected” methods.
IIRC, it means that any explicit receiver must be in the same class or
subclass as the sender. I’ve never used it.

Instance variables are only directly accessible (i.e. as “@bar”) from
instance methods of the current object - there is no syntax available to
access them on a different object (e.g. “foo.@bar”). This makes them
“private” by ruby’s definition of private. To access them on a different
object, you’d need foo.instance_variable_get(:@bar), which can be called
from anywhere.

Since Ruby’s protection mechanisms can be bypassed, “private” and
“protected” are really just API hints. If you have to code awkwardly as

foo.instance_variable_get(:@bar)
or
foo.send(:bar)

then it’s a hint that the author didn’t intend you to do this. But there
may still be good reasons to do it: for example, the IPAddr class
doesn’t provide any way to access the netmask or prefix length without
either doing this, or monkey-patching/subclassing. It can also be useful
when testing internals, or when initializing where you don’t want to
expose a setter method:

class MyStruct
def self.inherited(subclass)
subclass.instance_variable_set(:@foo, {})
end
end

class X < MyStruct; end # class auto-initialized

In that example, you might argue that a protected accessor method would
be cleaner:

class MyStruct
def self.inherited(subclass)
subclass.foo = {}
end

def self.foo=(v)
  @foo=v
end

class << self; protected :foo=; end

end

But the former code gets the job done with the minimum of fuss.