6

Folks, I am learning ruby and recently moved from JAVA. In JAVA I could make a member variable of a class static and that member variable would remain the same across instances of the class. How do I achieve the same in ruby. I did something like this in my ruby class:

class Baseclass

  @@wordshash

end

This seems to serve the purpose so far while I am testing this, that is @@wordhash remains the same across instances of Baseclass. Is my understanding correct.

Also, I wanted to have a member method in the class that is equivalent of a static method in JAVA(I do not require to have an instance of the class to access this). How can I do this? For example I want to have a method in the Baseclass like getwordshash() which returns @@wordshash and the user of that method should not have to make an instance of Baseclass().So something like this:

class Baseclass

  @@wordshash

  #static or class method
  def getwordhash()
    return @@wordshash
  end
end

and then I can use it like

#without making an instance
@hash = Baseclass.getwordhash()

I apologize if this is a very naive question, i am really new to ruby but very excited to learn.

Baldrick
  • 23,882
  • 6
  • 74
  • 79

2 Answers2

13

Using class variables as static store has unintended consequences in sub classes. You can easily implement static store by declaring an instance variable at the class level.

class Foo

  # initialize a static variable
  @names = ['Tom', 'Dick', 'Harry']

  # class method (notice the self. prefix
  def self.names
    @names
  end

  # instance methods

  def names
    @names
  end

  def names=val
    @names = val
  end

end

Let us print the static names

>> Foo.names
=> ["Tom", "Dick", "Harry"]

Let us print the instance variable

>> f = Foo.new
>> f.names
=> nil

Let us set the instance variable and try to print it again

>> f.names=["Bob", "Danny"]
=> ["Bob", "Danny"]

>> f.names
=> ["Bob", "Danny"]

Let us print the static variable again

>> Foo.names
=> ["Tom", "Dick", "Harry"]

I use the term static loosely. In reality both variables are instance variables. The @names declared in the class context is an instance variable for the Foo class object and @names inside a method is the instance variable of an instance of Foo class. Since there will ever be one object representing the type Foo, we can consider @names declared in the class context to be a static variable.

Harish Shetty
  • 64,083
  • 21
  • 152
  • 198
  • is it possible to use some variation of the shorthand: `attr_accessor` for access to these quasi class instance variables? – Dennis Sep 04 '13 at 18:59
  • 1
    @DennisHodapp have you tried using `cattr_accessor` and `mattr_accessor` methods? – Harish Shetty Feb 13 '14 at 04:11
  • no I haven't, but it seems those accessors are extensions of rails and I would rather not have to import them for a Ruby application. – Dennis Feb 13 '14 at 11:59
  • @DennisHodapp, you don't need the entire rails for the feature. You just need ActiveSupport gem(http://rubygems.org/gems/activesupport). Here is a another way to use `attr_accessor` to do the same: http://stackoverflow.com/a/895752/163203 – Harish Shetty Feb 13 '14 at 18:29
7
def self.getwordhash
  @@wordshash
end

With Ruby and Rails Naming Conventions:

class Baseclass

  @@words_hash = Hash.new

  def self.words_hash
    @@words_hash
  end
end
Baldrick
  • 23,882
  • 6
  • 74
  • 79