Class variables per subclasses, defined in the superclass

Discussion in 'Ruby' started by Gareth Adams, Dec 11, 2007.

  1. Gareth Adams

    Gareth Adams Guest

    Hi guys,

    First the pastie, I got class_eval from #ruby-lang on freenode -
    http://pastie.caboo.se/127003

    I've commented out the Rails specific stuff so I'm sure this is a Ruby question.

    What I'm trying to do is have a per-subclass variable created by a class method
    on the super class (which is called from the subclass). Fun.

    When I load in the file above I get

    -- Processor::Sponge.related_questions
    => {:surname=>1, :email=>1, :location=>1, :phone_number=>1, :forename=>1}
    -- Processor::CampaignMonitor.related_questions
    => {:surname=>1, :email=>1, :location=>1, :phone_number=>1, :forename=>1}
    -- Processor::Base.related_questions
    => {:surname=>1, :email=>1, :location=>1, :phone_number=>1, :forename=>1}

    where the expected output is

    -- Processor::Sponge.related_questions
    => {:location=>1, :phone_number=>1}
    -- Processor::CampaignMonitor.related_questions
    => {:surname=>1, :email=>1, :forename=>1}
    -- Processor::Base.related_questions
    => {} # possibly nil, it's not too important as it shouldn't be called directly

    I'll be the first to admit I don't really understand class variables, is what
    I'm trying to do possible without having to add anything to the subclass?
    Gareth Adams, Dec 11, 2007
    #1
    1. Advertising

  2. Alle marted=EC 11 dicembre 2007, Gareth Adams ha scritto:
    > Hi guys,
    >
    > First the pastie, I got class_eval from #ruby-lang on freenode -
    > http://pastie.caboo.se/127003
    >
    > I've commented out the Rails specific stuff so I'm sure this is a Ruby
    > question.
    >
    > What I'm trying to do is have a per-subclass variable created by a class
    > method on the super class (which is called from the subclass). Fun.
    >
    > When I load in the file above I get
    >
    > -- Processor::Sponge.related_questions
    > =3D> {:surname=3D>1, :email=3D>1, :location=3D>1, :phone_number=3D>1, :f=

    orename=3D>1}
    > -- Processor::CampaignMonitor.related_questions
    > =3D> {:surname=3D>1, :email=3D>1, :location=3D>1, :phone_number=3D>1, :f=

    orename=3D>1}
    > -- Processor::Base.related_questions
    > =3D> {:surname=3D>1, :email=3D>1, :location=3D>1, :phone_number=3D>1, :f=

    orename=3D>1}
    >
    > where the expected output is
    >
    > -- Processor::Sponge.related_questions
    > =3D> {:location=3D>1, :phone_number=3D>1}
    > -- Processor::CampaignMonitor.related_questions
    > =3D> {:surname=3D>1, :email=3D>1, :forename=3D>1}
    > -- Processor::Base.related_questions
    > =3D> {} # possibly nil, it's not too important as it shouldn't be called
    > directly
    >
    > I'll be the first to admit I don't really understand class variables, is
    > what I'm trying to do possible without having to add anything to the
    > subclass?


    I think you need class instance variable, not class variables. Class instan=
    ce=20
    variable are instance variables of the class object itself. For example:

    class A
    @var =3D 1
    end

    They follow the usual rules for instance variables. For example, to access=
    =20
    them from outside self (and this includes accessing them from instance=20
    methods of the class), you need to provide suitable methods:

    class A

    @var =3D 1
    =20
    def self.var
    @var
    end=20

    def a_method
    puts self.class.va
    end

    end

    Unlike class variables, class instance variables arent shared between paren=
    t=20
    and children classes, so they should work for you (unless Rails, which I=20
    don't know, requires class variables, of course).

    To use class instance variables, you should replace @@related_questions wit=
    h=20
    @related_questions and remove the call to class_eval (they aren't needed=20
    anymore).

    I hope this helps

    Stefano
    Stefano Crocco, Dec 11, 2007
    #2
    1. Advertising

  3. Gareth Adams

    Phrogz Guest

    On Dec 11, 10:58 am, Gareth Adams <> wrote:
    > What I'm trying to do is have a per-subclass variable created by a class method
    > on the super class (which is called from the subclass). Fun.


    class Base
    @thing1 = "Base 1"
    class << self
    attr_accessor :thing1
    attr_reader :thing2
    end
    def self.thing2=( val )
    @thing2 = "I am Thing2, and my value is '#{val}'"
    end
    self.thing2 = 'Base'
    end

    p Base.thing1, Base.thing2
    #=> "Base 1"
    #=> "I am Thing2, and my value is 'Base'"

    # Set values for subclasses in the class...
    class Bar < Base
    @thing1 = "Barthing1"
    end
    # ...or later
    Bar.thing2 = "Barthing2"

    p Bar.thing1, Bar.thing2
    #=> "Barthing1"
    #=> "I am Thing2, and my value is 'Barthing2'"

    # But since class instance variables aren't shared
    # the base class (and other subclasses) are unchanged
    p Base.thing1, Base.thing2
    #=> "Base 1"
    #=> "I am Thing2, and my value is 'Base'"
    Phrogz, Dec 11, 2007
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Razvan
    Replies:
    1
    Views:
    413
    tony vee
    Sep 10, 2004
  2. Replies:
    5
    Views:
    2,542
  3. Evan Klitzke
    Replies:
    0
    Views:
    361
    Evan Klitzke
    Aug 2, 2007
  4. Marko

    Superclass and Subclasses

    Marko, Sep 1, 2007, in forum: C++
    Replies:
    14
    Views:
    477
    Marko
    Sep 1, 2007
  5. bart van deenen
    Replies:
    6
    Views:
    752
    bart van deenen
    Mar 3, 2009
Loading...

Share This Page