How come I can't use "static" for methods and properties? 12

Posted by jeff Saturday, October 08, 2005 02:11:00 GMT

Those of us from a C#/C++ background are accustomed to “static” methods and fields in our classes. But using “static” in Rails classes just seems to throw wild compiler errors. What gives?

Doesn’t Ruby have a notion of static-ness for methods and variables?

Of course it does. But declaring them is a little bit different from what you’re used to, and probably not guessable.

And like a good developer you’re too lazy to read any documentation about it, so it’s a good thing you came across this article.


To declare a static field, called a class variable in Ruby, just use two at-signs:

def doSomething
  @@didSomething += 1
  puts "I've done this #{@@didSomething} times now." 
end

That wasn’t so bad now, was it?

Static methods are a little trickier. There are actually two ways to declare a static method, called (you guessed it) a class method in Ruby. Let’s say we want our code above to be a class method instead of an instance method:

def MyClassName.doSomething
  ...
end

All we did is put the class name in front of the method name.

Another acceptable form that you’ll see a lot is:

def self.doSomething
  ...

which can be quite deceiving if you guessed that “self” is the equivalent of “this” in C++/C#, which it is definitely not.

So remember:

@@ => static field

className.methodName => static method

self.methodName => static method

Now go write some class methods that access some class variables, you crazy Ruby expert you!

Comments

Leave a response

  1. Jules   February 25, 2006 @ 08:19 PM

    Self in ruby IS this in C#. Really.

    In a class definition, self is the class:

    class Foo print self end

    will print the class' name.

    This will do the same:

    print Foo

    So, self is the same as Foo (at least between class ... end).

    And now guess why this works:

    def self.doSomething

    like:

    def Foo.doSomething

    A last comment, common principle in ruby is: do_something instead of doSomething.

  2. Jeff   February 27, 2006 @ 05:24 PM

    Jules, "self" in Ruby is really not the equivalent of "this" in C#. "this" is always pointer to an object instance. (In C++, it was a parameter passed implicitly to each instance method so that the vtable lookups would find the right method, and also to identify which object's state should be accessed by member variables for the duration of the method call).

    In Ruby, "self" refers to the current "receiver": could be an object if you're in the midst of an instance method definition; could be the class itself if you're in the midst of a class definition outside of a method definition; and so on. Because Ruby class "definitions" are actually interpreted on the fly, the meaning of "self" changes at different points in the definition.

    I just wanted to highlight this fact for those of us new to Ruby who might see the word "self" in Ruby examples, assume it's the same as "this", and get really confused trying to understand the Ruby code that way.

    But you're right, I probably should have named the ruby method "do_something".

  3. khang.toh@gmail.com   March 13, 2006 @ 10:03 PM

    Hey Jeff

    Have you tried doing the @@dosomething in rails?

    I tried and I kept getting @@dosomething = 1 when everytime I call the action under the controller class that I declared.

    Any idea?

  4. Jeff   March 13, 2006 @ 10:35 PM

    Class variables in Rails controllers won't usually work. Controllers are created and destroyed for every action that is called, and apparently the Ruby GC removes the class variables when instances of that class no longer exist (a little strange, I know).

    But, class variables in controllers indicate usually indicate a design flaw. Storing controller data in a class variable won't scale if you add more than one web server, for example; each action could be handled by a different server. Depending on what you're actually trying to do, you should store your static data in your database, or in the session hash. Those are probably the best ways to persist data across web requests. Again, it's hard to recommend something specific without details, but I hope that helps point you in the right direction.

  5. khangtoh   March 14, 2006 @ 06:38 PM

    Thanks!

    I am trying to write a product scroller in one of controllers.

    So basically, I have an array of the products that I want the product scroller to display over time.

    def shownextitem @@ += 1 @currentitem = @products[@@index] end

    So now I see why this is not possible. I think the session hash seems like good solution.

  6. Information On Argentina   April 28, 2006 @ 08:48 AM

    I'm working...

  7. Grandmother Shirt   April 28, 2006 @ 10:11 AM

    I was very dissapointed of this!

  8. Stephen   August 23, 2007 @ 03:17 PM

    It seems that neither static or global variables work inside a controller or model object. This makes it very difficult (impossible?) to create singleton meta-data objects. Having to recreate the same object structure for every web page load seems very wasteful, when one copy of it could serve all users.

  9. Stephen   August 23, 2007 @ 10:41 PM

    Thought I give a possible work around. It is ugly, but it works. You can add definition of global variables to your environment.rb file in the config folder. This works. They are created only once and persist as long as WEBrick is running. Controllers can access them just fine, as well. Not sure what will happen with FastCGI, but I think it will work since it stores static state.

    Ugly, but workable. Hope that helps someone.

  10. caocao   February 18, 2008 @ 02:59 AM

    @@ doesn't work in test env but it works in production env. Rails loads always every class in test env which causes the lost of @@ value.

  11. kino   May 24, 2008 @ 01:09 AM

    By immersing ourselves meditatively in the general intentions of experiences, we discover that noetic acts, by this preliminary work, here roughly indicated rather than done explicitly, are unified synthetically.

  12. Ellroy   May 30, 2008 @ 11:17 PM

    The phenomena, in reference to ends, can be treated like the objects in space and time.

Comment


(won't be published)