Accessing class variables from the outside (beginner question)

I am still learning Ruby and I am trying to get something
like this to work and am unsure how.

I know I could do attr_reader to
access “ones” but ones might be an
array, hash, etc.

Is there a way to do something like this:
class Test
def initialize
@try[“hashworld”] = 10000
@ones = 1,2,3,4
end
def addit(one,two)
#can code add one + two, from
#inside and outside?
return(one + two)
end
end
tens = 10,20,30,40,50
a = Test.new
p a.addit(ones[1],tens[0]) #prints 12
p a.addit(tens[3],ones[0]) #prints 41
p a.addit(tens[3],try[“hashworld”]) #prints 10040

Thanks,
Tom

Hi –

On Tue, 10 Jun 2008, [email protected] wrote:

I am still learning Ruby and I am trying to get something
like this to work and am unsure how.

You don’t have any class variables in your example, only instance
variables. Class variables look like this: @@var, and in most cases
aren’t what you want to use anyway.

I know I could do attr_reader to access “ones” but ones might be an
array, hash, etc.

Is there a way to do something like this:
class Test
def initialize
@try[“hashworld”] = 10000

@try is nil at this point; you can’t index it.

@ones = 1,2,3,4

end
def addit(one,two)
#can code add one + two, from
#inside and outside?
return(one + two)
end
end
tens = 10,20,30,40,50
a = Test.new

You’ll get a fatal error at this point if you run this code.

p a.addit(ones[1],tens[0]) #prints 12
p a.addit(tens[3],ones[0]) #prints 41
p a.addit(tens[3],try[“hashworld”]) #prints 10040

You haven’t defined try. (It has no connection to the @try inside the
Test#initialize method, which you also haven’t defined.)

I’m not sure exactly what you want to do but I think you’re
overthinking it. Basically, instance variables (like @try) are visible
only to the object that owns them. If that object wants to expose them
to other objects, it has to provide methods for that purpose.
attr_reader is a macro that writes such a method for you, such that
this:

attr_reader :ones

is the same as this:

def ones
@ones
end

but shorter.

David

On Tuesday 10 June 2008, [email protected] wrote:

 @try["hashworld"] = 10000

p a.addit(ones[1],tens[0]) #prints 12
p a.addit(tens[3],ones[0]) #prints 41
p a.addit(tens[3],try[“hashworld”]) #prints 10040

Thanks,
Tom

As first thing, variables like @try and @ones in your code are not class
variables, as the subject of your post implies, but instance variables.
Class
variables are something else (their names start with @@, are shared
among the
class object itself, its instances, derived class objects and their
instances).

Regarding your question. The only way to access instance variables from
outside the instance is to create accessor methods for them. You can do
it
using attr_reader and similar, or you can write them by hand. For
example:

class Test

def ones
@ones
end

end

I hope this helps

Stefano

On Jun 9, 2008, at 22:15 , David A. Black wrote:

Class variables […] in most cases aren’t what you want to use
anyway.

While probably true in this case, I think this statement is
dangerously loaded… Your words have sway and affect design
decisions. Sometimes class variables are exactly the right tool for
the job:

% find */dev/{lib,test} -name *.rb | xargs grep -l @@ | wc -l
50

Sometimes class variables are exactly the right tool for the job

Where would you recommend using class variables over class level
instance variables?

On Jun 10, 4:14 am, Paul McMahon [email protected] wrote:

Sometimes class variables are exactly the right tool for the job

Where would you recommend using class variables over class level
instance variables?

if you want a variable available to all instances that says how many
instances exist. If you want to create an ID that increments with
each instance. If you are storing a path that may change, but all
instances will use it. If you want to update scaling criteria on
several objects at once, having a class variable set to twips, pixels,
or inches could be just the right tool. And on and on and on…

On Tue, Jun 10, 2008 at 9:16 AM, Ryan D. [email protected]
wrote:

 50

May I suggest to trust David more than grep ;). I do not know of any
usecase where class variables are the right thing to use, but I am
eager to learn, so please enlighten me.

Cheers
Robert


http://ruby-smalltalk.blogspot.com/


As simple as possible, but not simpler.
Albert Einstein

On Tue, Jun 10, 2008 at 8:11 AM, Stefano C.
[email protected] wrote:

Regarding your question. The only way to access instance variables from
outside the instance is to create accessor methods for them.
Hmm I do not know what to say, of course it is possible, but you are
probably right not talking about metaprogramming to a nuby ;).


http://ruby-smalltalk.blogspot.com/


As simple as possible, but not simpler.
Albert Einstein

On Jun 10, 2008, at 05:01 , Robert D. wrote:

loaded… Your words have sway and affect design decisions.
Sometimes class
variables are exactly the right tool for the job:

% find */dev/{lib,test} -name *.rb | xargs grep -l @@ | wc -l
50

May I suggest to trust David more than grep ;). I do not know of any
usecase where class variables are the right thing to use, but I am
eager to learn, so please enlighten me.

that is a grep on MY code… I trust my code more than I trust your
trust. :stuck_out_tongue:

On Tuesday 10 June 2008, Robert D. wrote:

On Tue, Jun 10, 2008 at 8:11 AM, Stefano C. [email protected]
wrote:

Regarding your question. The only way to access instance variables from
outside the instance is to create accessor methods for them.

Hmm I do not know what to say, of course it is possible, but you are
probably right not talking about metaprogramming to a nuby ;).

Of course, you’re right. I meant: the normal way to access instance
variables
from the outside is to create accessor methods for them. There are other
ways,
for example the instance_variable_set and instance_variable_get methods,
but
they should be used only when in special cases.

Stefano

Hi –

On Wed, 11 Jun 2008, Ryan D. wrote:

While probably true in this case, I think this statement is dangerously

that is a grep on MY code… I trust my code more than I trust your trust. :stuck_out_tongue:

Also, I’m not saying that there are no uses for class variables. And
grep is our friend; it’s how we demonstrate, for example, that
camelCase variable names are virtually unheard of :slight_smile: I’ll stand by my
“in most cases”, though, with regard to class variables.

David

if you want a variable available to all instances that says how many
instances exist. If you want to create an ID that increments with
each instance. If you are storing a path that may change, but all
instances will use it. If you want to update scaling criteria on
several objects at once, having a class variable set to twips, pixels,
or inches could be just the right tool. And on and on and on…

Perhaps I wasn’t clear enough. As far as I know, you can accomplish all
that using class level instance variables. For example, consider the
following code:

class ClassLevelVariables
@instance_count = 0
class << self
attr_accessor :instance_count
end

def initialize
ClassLevelVariables.instance_count += 1
end
end

class ClassVariables
@@instance_count = 0
class << self
def instance_count
@@instance_count
end
end

def initialize
@@instance_count += 1
end
end

[ClassLevelVariables, ClassVariables].each do |klass|
puts klass.instance_count
klass.new
puts klass.instance_count
end

The code is almost equivalent, and I was just wondering when one style
is prefered over the other.