0

I'm somewhat new to ruby, only being called upon to maintain some old, undocumented code here and there. I have a base class in ruby where I put a hash class variable.

@@projects = Hash.new

And I want my derived classes to add to it via a method (passing in a parameter). The problem is, it seems like each derived class has its own copy of the hash, instead of accessing a single 'static' version of it.

Could someone help?

class Base
   @@projects = Hash.new
   def AddSomething key, value
       @@projects[key] = value
   end
end

class Derived < Base
   def initialize
      ...
      AddSomething key, value
      ...
   end
end

So, in the code sample above, every time I add a value to @@projects in the AddSomething function the size/length of the hash is always 1, it never grows. It acts as if it's an instance variable which is not what I want.

Any ideas? I'm stumped here.

2 Answers 2

1

Probably something is wrong in the code hidden behind ... in your initializer of Derived. The code below works for me just fine:

irb(main):032:0> class Base
irb(main):033:1>   @@projects = {}
irb(main):034:1>   def add(k, v)
irb(main):035:2>     @@projects[k] = v
irb(main):036:2>   end
irb(main):037:1> end
=> nil
irb(main):038:0> class Derived < Base
irb(main):039:1>   def initialize(k, v)
irb(main):040:2>     add(k, v)
irb(main):041:2>   end
irb(main):042:1> end
=> nil
irb(main):048:0> Derived.send(:class_variable_get, :@@projects)
=> {}
irb(main):049:0> Derived.new(1,2)
=> #<Derived:0xb777be6c>
irb(main):050:0> Derived.send(:class_variable_get, :@@projects)
=> {1=>2}
irb(main):051:0> Derived.new(3,4)
=> #<Derived:0xb7772fb0>
irb(main):052:0> Derived.send(:class_variable_get, :@@projects)
=> {1=>2, 3=>4}

UPD: Let me put it differently:

irb(main):053:0> class Base
irb(main):054:1>    @@projects = {}
irb(main):055:1>    def add(k, v)
irb(main):056:2>      @@projects[k] = v
irb(main):057:2>      p @@projects
irb(main):058:2>    end
irb(main):059:1> end
=> nil
irb(main):060:0> class Derived < Base
irb(main):061:1>    def initialize(k, v)
irb(main):062:2>      add(k, v)
irb(main):063:2>    end
irb(main):064:1> end
=> nil
irb(main):065:0> 
irb(main):066:0* Derived.new(1, 2)
{1=>2}
=> #<Derived:0xb77ae40c>
irb(main):067:0> Derived.new(:a, :b)
{:a=>:b, 1=>2}
=> #<Derived:0xb77a0500>
irb(main):068:0> Derived.new(:c, :d)
{:a=>:b, :c=>:d, 1=>2}
=> #<Derived:0xb779ace0>
Sign up to request clarification or add additional context in comments.

4 Comments

wo, hold on. What is this send stuff? Looks like you are reflecting over something, the syntax of which looks like a deep secret of Ruby.
Ah, but I'm using strings, not these :thingies (What ever you call them... names?)
@CJohnson In Ruby, the :thingies are called 'symbols'.
Ah I figured it out. I was putting @@projects = Hash.new in the initialize method of the base class. I didn't realize my code example was different from the actual code was working on till this morning. So once I took that out of the initialize method it worked as expected. I got the impetus to look at it again by looking at your example code.
0

It looks like Derived#initialize does not take any argument. Where do the key and value passed to AddSomething come from? If they are constant, then of course @@projects remains to have length 1 because you would keep adding the same key and value to the hash.

1 Comment

The variables key and value are generated in the initialize method from various code. The arguments to the initialize method are not related to the issue here. I've debugged the values for key and value, and they are what I expect: Unique associated pairs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.