Accessing class instance variables from an instance?

Hi there,

I'm writing a class to encapsulate a 'job'. The job will have variables
such as name, id, resources, dependencies etc and some of these will be
common across all instances. I'd like to be able to set these common
variables once and not have to repeat it for every instance. What's the
best way of accomplishing this?

So far I've seen a lot of articles that steer you towards using class
instance variables instead of class variables but I can't find examples
of how to use these from within an instance. Is that possible?

Thanks.

···

--
Posted via http://www.ruby-forum.com/.

An instance variable is prefaced by @, where a class variable is
prefaced by @@. Here's a small example:

class Thingy
  @@thingies = 0
  def initialize(name)
    @my_name = name
    @@thingies += 1
    puts "A new thingy is here!"
  end

  def whatsMyName
    puts "This thingy is named '#{@my_name}'."
  end

  def howMany?
    puts "So far you have created #{@@thingies} thingies."
  end
end

The @@thingies class variable is shared by all instances of the class.
Changing that variable in any one of the classes will change it for all
of them.

Is this what you were looking for?

···

--
Posted via http://www.ruby-forum.com/.

Isn't that just a more complicated way of doing roughly the same thing?
Are there advantages or disadvantages involved in using one or the
other?

···

--
Posted via http://www.ruby-forum.com/.

That's interesting. I never considered how they'd behave under
inheritance. Has there been a discussion about changing the behavior so
that the subclasses don't alter the superclass variable? (Like the
subclass would copy in the superclass var at definition but it would be
a separate instance from the superclass object.)

···

--
Posted via http://www.ruby-forum.com/.

Actually, now that I'm thinking about it the existing behavior sort of
what makes more sense. I'd think that subclasses would be better
instantiating their own class vars rather than expecting a unique copy
of the superclass var. I can see why you'd want the class instance vars
rather than modifying the existing mechanic. On the other hand, maybe a
new variable type to encapsulate the behavior of a class instance var in
the way that it's being used here would be something worth discussing?

···

--
Posted via http://www.ruby-forum.com/.

Probably a better way than adding a new var type but it could be more
versatile than just for use with civ for subclasses. Maybe something
like 'self_attr_accessor' or 'class_attr_accessor'?

···

--
Posted via http://www.ruby-forum.com/.

<<self is very bad because it starts an multiline string

allways do << self with an " "

···

--
Posted via http://www.ruby-forum.com/.

Concerning an attr for civ's, would it really be detrimental, though?
True it's something that would very rarely be used, but it almost feels
like it's something that belongs there. I guess what I mean is, if
attr_accessor exists it feels to me like there should be a sort of
class-level equivalent. Maybe that's just me, though. This has
somewhat moved beyond my depth.

···

--
Posted via http://www.ruby-forum.com/.

I once spent almost two hours locating a bug.

In old ruby code I wrote years ago.

Turned out I used class variables.

I then also understood that there was no need for me to use them.

Since I wasted time, and also had a bug, I decided that day to no longer
use class variables at all.

There are a very few use cases where they may seem not totally useless,
but so far I myself did not need them at all. And I follow a philosophy
that less (code) is more.

···

--
Posted via http://www.ruby-forum.com/.

I think he is looking for class instance variables.

class Foo
  @class_ivar = 3

  def self.class_ivar() @class_ivar; end

  def bar(a)
    puts "#{a} + #{self.class.class_ivar} = #{a + self.class.class_ivar}"
  end
end

foo = Foo.new
foo.bar(6) # 6 + 3 = 9

cr

···

On Dec 20, 2011, at 12:26 PM, Khat Harr wrote:

An instance variable is prefaced by @, where a class variable is
prefaced by @@. Here's a small example:

class Thingy
@@thingies = 0
def initialize(name)
   @my_name = name
   @@thingies += 1
   puts "A new thingy is here!"
end

def whatsMyName
   puts "This thingy is named '#{@my_name}'."
end

def howMany?
   puts "So far you have created #{@@thingies} thingies."
end
end

The @@thingies class variable is shared by all instances of the class.
Changing that variable in any one of the classes will change it for all
of them.

Is this what you were looking for?

Class variables are bad. Usually.

I don't see any point in that, class ivars seem sufficient to me. What
would be nice, though, is an attr_accessor equivalent that defines methods
for both the class and instance.

(overly simple example)

class Class
  def whatever_accessor(meth_name)
    delegate_to_class meth_name
    singleton_class.instance_eval do
      attr_accessor meth_name
    end
  end

  def delegate_to_class(meth_name)
    define_method meth_name do |*args, &block|
      self.class.send meth_name, *args, &block
    end
  end
end

class Foo
  whatever_accessor :bar
  self.bar = :baz
end

Foo.new.bar # => :baz

···

On Tue, Dec 20, 2011 at 9:42 PM, Khat Harr <myphatproxy@hotmail.com> wrote:

Actually, now that I'm thinking about it the existing behavior sort of
what makes more sense. I'd think that subclasses would be better
instantiating their own class vars rather than expecting a unique copy
of the superclass var. I can see why you'd want the class instance vars
rather than modifying the existing mechanic. On the other hand, maybe a
new variable type to encapsulate the behavior of a class instance var in
the way that it's being used here would be something worth discussing?

--
Posted via http://www.ruby-forum.com/\.

Huh?

`class "Foo"` isn't valid syntax for a class definition, so the presence of
"class" disambiguates it.

class X
  class <<self
    def foo
      :foo
    end
  end

  class << self
    def bar
      :bar
    end
  end
end

X.foo #=> :foo
X.bar #=> :bar

(But in this case, I think `def self.foo` is better.)

···

On Wed, Dec 21, 2011 at 11:57, Hans Mackowiak <hanmac@gmx.de> wrote:

<<self is very bad because it starts an multiline string

allways do << self with an " "

<<self is very bad because it starts an multiline string

In this case, it is not.

Concerning an attr for civ's, would it really be detrimental, though?

Do you mean an attr_accessor like method for a class instance itself?

True it's something that would very rarely be used, but it almost feels
like it's something that belongs there. I guess what I mean is, if
attr_accessor exists it feels to me like there should be a sort of
class-level equivalent. Maybe that's just me, though. This has
somewhat moved beyond my depth.

If you mean such a method then yes, that might be a reasonable thing to have.

Kind regards

robert

···

On Wed, Dec 21, 2011 at 6:48 PM, Khat Harr <myphatproxy@hotmail.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Actually, now that I'm thinking about it the existing behavior sort of
what makes more sense. I'd think that subclasses would be better
instantiating their own class vars rather than expecting a unique copy
of the superclass var. I can see why you'd want the class instance vars
rather than modifying the existing mechanic. On the other hand, maybe a
new variable type to encapsulate the behavior of a class instance var in
the way that it's being used here would be something worth discussing?

I opt for completely removing class variables because they lead to
confusion without end. I don't see the need for a new type of
variable either. For one, it is an open question if state really
should be managed on the class level. It may be much more appropriate
for Shareed to have a container object which holds a number of
instances and manages common state. If you need that state in
instances you can always have a backward reference to the container.
(You need that anyway if you want to avoid joining multiple containers
for a 1:n relationship.) If state is managed by the class then you
cannot partition the set of instances. And in case of this thread it
seems state is better not held in the class instance, because that
should manage class state while here we are talking about state which
is common to all instances. Just because it's easy to do or
convenient does not mean that storing this in the class is necessary a
good idea.

I don't see any point in that, class ivars seem sufficient to me. What
would be nice, though, is an attr_accessor equivalent that defines methods
for both the class and instance.

I find that a bad idea: this easily leads to confusion and if you want
the same attribute in the class and all instances then you better make
that explicit. This should be a very rare case anyway. The only
thing which comes to mind where this seems remotely useful would be
default values for fields. But in this case I'd rather name fields
differently because they mean something different:

class Foo
  class <<self
    attr_accessor :name_default
  end

  attr_writer :name

  def name
    @name || self.class.name_default
  end
end

irb(main):025:0> Foo.name_default = "X"
=> "X"
irb(main):026:0> f = Foo.new
=> #<Foo:0x1018c06c>
irb(main):027:0> f.name
=> "X"
irb(main):028:0> f.name = "bar"
=> "bar"
irb(main):029:0> f.name
=> "bar"
irb(main):030:0> Foo.name_default
=> "X"

Kind regards

robert

···

On Wed, Dec 21, 2011 at 5:34 AM, Josh Cheek <josh.cheek@gmail.com> wrote:

On Tue, Dec 20, 2011 at 9:42 PM, Khat Harr <myphatproxy@hotmail.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Robert Klemme wrote in post #1037737:

···

On Wed, Dec 21, 2011 at 6:48 PM, Khat Harr <myphatproxy@hotmail.com> > wrote:

Concerning an attr for civ's, would it really be detrimental, though?

Do you mean an attr_accessor like method for a class instance itself?

Yup.

--
Posted via http://www.ruby-forum.com/\.

Yeah, sorry, it was late. The need I actually come across isn't state
based, but functionality based. For example, HTTParty's get method. From
outside it's nice to be able to say `HTTParty.get(...)` but from inside
they don't want to have to say `self.class.get(...)` so that is an example
of a class level method that should be available to instances without
having to go find the class. I find that need occasionally. Or sometimes
I'm looking at some method and realizing it really could be a class method,
and that no one can use it without instantiating, but it's pretty obnoxious
to have to instantiate a class just to call some method that doesn't depend
on instances.

···

On Wed, Dec 21, 2011 at 2:50 AM, Robert Klemme <shortcutter@googlemail.com>wrote:

On Wed, Dec 21, 2011 at 5:34 AM, Josh Cheek <josh.cheek@gmail.com> wrote:
> On Tue, Dec 20, 2011 at 9:42 PM, Khat Harr <myphatproxy@hotmail.com> > wrote:
>
>> Actually, now that I'm thinking about it the existing behavior sort of
>> what makes more sense. I'd think that subclasses would be better
>> instantiating their own class vars rather than expecting a unique copy
>> of the superclass var. I can see why you'd want the class instance vars
>> rather than modifying the existing mechanic. On the other hand, maybe a
>> new variable type to encapsulate the behavior of a class instance var in
>> the way that it's being used here would be something worth discussing?

I opt for completely removing class variables because they lead to
confusion without end. I don't see the need for a new type of
variable either. For one, it is an open question if state really
should be managed on the class level. It may be much more appropriate
for Shareed to have a container object which holds a number of
instances and manages common state. If you need that state in
instances you can always have a backward reference to the container.
(You need that anyway if you want to avoid joining multiple containers
for a 1:n relationship.) If state is managed by the class then you
cannot partition the set of instances. And in case of this thread it
seems state is better not held in the class instance, because that
should manage class state while here we are talking about state which
is common to all instances. Just because it's easy to do or
convenient does not mean that storing this in the class is necessary a
good idea.

> I don't see any point in that, class ivars seem sufficient to me. What
> would be nice, though, is an attr_accessor equivalent that defines
methods
> for both the class and instance.

I find that a bad idea: this easily leads to confusion and if you want
the same attribute in the class and all instances then you better make
that explicit. This should be a very rare case anyway. The only
thing which comes to mind where this seems remotely useful would be
default values for fields. But in this case I'd rather name fields
differently because they mean something different:

class Foo
class <<self
   attr_accessor :name_default
end

attr_writer :name

def name
   @name || self.class.name_default
end
end

irb(main):025:0> Foo.name_default = "X"
=> "X"
irb(main):026:0> f = Foo.new
=> #<Foo:0x1018c06c>
irb(main):027:0> f.name
=> "X"
irb(main):028:0> f.name = "bar"
=> "bar"
irb(main):029:0> f.name
=> "bar"
irb(main):030:0> Foo.name_default
=> "X"

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

-----Messaggio originale-----

···

Da: Khat Harr [mailto:myphatproxy@hotmail.com]
Inviato: martedì 27 dicembre 2011 01:43
A: ruby-talk ML
Oggetto: Re: Accessing class instance variables from an instance?

Robert Klemme wrote in post #1037737:

On Wed, Dec 21, 2011 at 6:48 PM, Khat Harr <myphatproxy@hotmail.com> > wrote:

Concerning an attr for civ's, would it really be detrimental, though?

Do you mean an attr_accessor like method for a class instance itself?

Yup.

--
Posted via http://www.ruby-forum.com/\.

--
Caselle da 1GB, trasmetti allegati fino a 3GB e in piu' IMAP, POP3 e SMTP autenticato? GRATIS solo con Email.it http://www.email.it/f

Sponsor:
Conto Arancio al 4,20%. Soldi sempre disponibili, zero spese, aprilo in due minuti!
Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid923&d)-12

Yeah, sorry, it was late. The need I actually come across isn't state
based, but functionality based. For example, HTTParty's get method. From
outside it's nice to be able to say `HTTParty.get(...)` but from inside
they don't want to have to say `self.class.get(...)` so that is an example

You can also say HTTParty.get(...) inside instance methods.

of a class level method that should be available to instances without
having to go find the class. I find that need occasionally. Or sometimes
I'm looking at some method and realizing it really could be a class method,
and that no one can use it without instantiating, but it's pretty obnoxious
to have to instantiate a class just to call some method that doesn't depend
on instances.

Well, then make it a class method. That has the added advantage that
you make the call explicit in instance methods which use it and it is
immediately clear that this method does not manipulate instance state.

I think this make-a-class-method-be-callable-as-instance-method looks
convenient on first sight but on second sight it may just be
obfuscation.

Kind regards

robert

···

On Wed, Dec 21, 2011 at 3:08 PM, Josh Cheek <josh.cheek@gmail.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/