Skip to content

Instantly share code, notes, and snippets.

@alakra
Created May 22, 2012 03:43
Show Gist options
  • Save alakra/2766431 to your computer and use it in GitHub Desktop.
Save alakra/2766431 to your computer and use it in GitHub Desktop.
Managing State at the Class Level in Ruby
#!/usr/bin/env ruby
# Class Variables
# One quick way to manage references between sub-classes through a parent class
# is to use a class variable. Class variable are designated by `@@` in front of a variable name.
# e.g.
class Foo
@@configuration_file = 'foo/bar.yml'
end
# The class variable `@@configuration_file` will be available in any child classes that inherit from `Foo`
# You can also define class variables in modules and have those carry over through inclusion or extension
# of that module in a class. So if you want to mixin some functionality on the fly and track it between
# the classes that include that module, that is available.
# e.g.
module Bar
@@queue = []
end
class Klass
include Bar
end
Klass.class_variable_get(:@@queue)
# Now, the getter interface for retrieving that class variable from the outside isn't pretty. I'd suggest
# using a custom setter to do something a bit nicer looking. There is also a setter interface:
Klass.class_variable_set(:@@queue, [])
# The above case is pretty interesting, because you don't want to replace the queue itself, but add or remove from it.
# Since you ruby passes by reference, you can do the following and we're good:
Klass.class_variable_get(:@@queue) << 5
# I think what we really want is something like this:
module Bar
@@queue = []
def queue
@@queue
end
end
class Foo
extend Bar
end
class Far
extend Bar
end
# You should notice that I used `extend` vs `include` so that I could "extend" my
# methods as class methods vs include methods in order to get the following:
Foo.queue << 5
Foo.queue.first
Foo.queue[1]
Far.queue << 2
Far.queue
# etc..
# Take a look at Far.queue or Foo.queue, you'll see that they both reference the same object.
# there's even more at http://rdoc.info/stdlib/core/Class
# If you need simple callback functionality, checkout the Observable module
# http://www.ruby-doc.org/stdlib-1.9.3/libdoc/observer/rdoc/Observable.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment