10

I understand (I think) the difference between class variables and instance variables of a class in Ruby.

I'm wondering how one can access the instance variables of a class from OUTSIDE that class.

From within (that is, in a class method instead of an instance method), it can be accessed directly, but from outside, is there a way to do MyClass.class.[@$#]variablename?

I don't have any specific reason for doing this, just learning Ruby and wondering if it is possible.

3 Answers 3

10
class MyClass @my_class_instance_var = "foo" class << self attr_accessor :my_class_instance_var end end puts MyClass::my_class_instance_var 

The foregoing yields:

>> foo 

I believe that Arkku demonstrated how to access class variables (@@), not class instance variables (@) from outside the class.

I drew the foregoing from this essay: Seeing Metaclasses Clearly

Sign up to request clarification or add additional context in comments.

Comments

3

Ruby has Class, Class Object, and Instance.

A Class variable belongs to a Class.
A Class instance variable belongs to a Class Object

Class variable:

Accessible within the class and its instances.
attr_accessor does not work on class variables.

Class instance variable:

Accessible only through the Class.
attr_accessor works if you define it in the class and not in the class object as below.

class A @b = 1 class << self attr_accessor :b end end 

Defining a getter and setter on the instances for the class instance variable b in:

class A @b = 1 class << self attr_accessor :b end def b A.b end def b=(value) A.b=value end end 

Now the class instance variable b can be accessed via the owner Class and its instances.
As a several days old ruby learner, this is the most I can do.

`irb(main):021:0* class A irb(main):022:1> @b = 1 irb(main):023:1> class << self irb(main):024:2> attr_accessor :b irb(main):025:2> end irb(main):026:1> def b irb(main):027:2> A.b irb(main):028:2> end irb(main):029:1> def b=(v) irb(main):030:2> A.b=v irb(main):031:2> end irb(main):032:1> end => :b= irb(main):033:0> A.b => 1 irb(main):034:0> c = A.new => #<A:0x00000003054440> irb(main):035:0> c.b => 1 irb(main):036:0> c.b= 50 => 50 irb(main):037:0> A.b => 50 irb(main):038:0>` 

Yes, I'm begining to dislike ruby...iso a better solution.

Comments

-1

In ruby you can achieve this in 2 ways

  1. manually defining getter and setters
  2. using attr_* methods

Let me elaborate the above ways for you,

Manually defining getter and setters

class Human def sex=(gender) @sex = gender end def sex @sex end end //from outside class human = Human.new // getter method call puts human.sex // setter method call to explicitly set the instance variable human.sex = 'female' puts human.sex // now this prints female which is set 

using attr_* methods

class Human attr_accessor :sex end //from outside human = Human.new // getter method call puts human.sex // setter method call to explicitly set the instance variable human.sex = 'female' puts human.sex // now this prints female which is set 

attr_accessor internally creates setter and getter methods for you, if you want only setter you can just use attr_writer and if you want only getter you can use attr_reader.

I hope, I answered your question

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.