accessing class variables from the outside (beginner question)

P

progcat

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
 
D

David A. Black

Hi --

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 :eek:nes

is the same as this:

def ones
@ones
end

but shorter.


David

--
Rails training from David A. Black and Ruby Power and Light:
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
ADVANCING WITH RAILS July 21-24 Edison, NJ
See http://www.rubypal.com for details and updates!
 
S

Stefano Crocco

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

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
 
R

Ryan Davis

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
 
P

Paul McMahon

Sometimes class variables are exactly the right tool for the job

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

`brad`

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......
 
R

Robert Dober

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

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
 
R

Robert Dober

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 ;).
 
S

Stefano Crocco

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
 
R

Ryan Davis

On Tue, Jun 10, 2008 at 9:16 AM, Ryan Davis <ryand-
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

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. :p
 
D

David A. Black

Hi --

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

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. :p

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 :) I'll stand by my
"in most cases", though, with regard to class variables.


David

--
Rails training from David A. Black and Ruby Power and Light:
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
ADVANCING WITH RAILS July 21-24 Edison, NJ
See http://www.rubypal.com for details and updates!
 
P

Paul McMahon

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top