|
Rootroute ruby language pages |
A class can be defined repeatedly. Each definition is added to the last definition. If a method is redefined, the former one is overridden and lost.
As of Ruby 1.5.3, there are. A variable prefixed with two at signs is a class variable, accessible within both instance and class methods of the class.
class CountEm
@@children = 0
def initialize
@@children += 1
@myNumber = @@children
end
def whoAmI
"I'm child number #@myNumber (out of #@@children)"
end
def CountEm.totalChildren
@@children
end
end
c1 = CountEm.new
c2 = CountEm.new
c3 = CountEm.new
c1.whoAmI # -> "I'm child number 1 (out of 3)"
c3.whoAmI # -> "I'm child number 3 (out of 3)"
CountEm.totalChildren # -> 3
|
Earlier versions of Ruby do not have class variables. However,
container classes (Array, Hash, etc) assigned to a
class constant can be used to give the same effect. This example uses
an array. Some folks feel hashes are better.
class Foo
F = [ 0 ] # pseudo class variable - Array 'F'
def foo
F[0] += 1
puts F[0]
end
end
|
This reports on the number of times foo is called across
all instances of class Foo.
class Foo
@a = 123 # (1)
def foo
p @a # (2) ... nil not 123
end
end
|
(1) is a class instance variable, and (2) is an ordinary
instance variable (which, not having been initialized, has a value of
nil). (2) belongs to an instance of class Foo,
and (1) belongs to the class object Foo, which is an
instance of Class class. (phew!)
There is no way to access class instance variables from instance methods.
A singleton method is an instance method associated with one specific object.
You create a singleton method by including the object in the definition:
class Foo end foo = Foo.new bar = Foo.new def foo.hello puts "Hello" end foo.hello bar.hello Produces: Hello prog.rb:10: undefined method `hello' for #<Foo:0x401b49a0> (NameError) |
Singleton methods are useful when you want to add a method to an object and creating a new subclass is not appropriate.
A singleton method of a class object is called a class method. (Actually, the class method is defined in the metaclass, but that is pretty much transparent). Another way of looking at it is to say that a class method is a method whose receiver is a class.
It all comes down to the fact that you can call class methods without having to have instances of that class (objects) as the receiver.
Let's create a singleton method of class Foo:
class Foo
def Foo.test
"this is foo"
end
end
#It is invoked this way.
Foo.test # -> "this is foo"
|
In this example, Foo.test is a class method.
Methods which are defined in class Class can
be used as class methods for every class(!)
A Singleton class is an anonymous class that is created by subclassing the class associated with a particular object. They are another way of extending the functionality associated with just one object.
Take the lowly Foo:
class Foo # -> hello<<7>>nil
def hello
print "hello"
end
end
foo = Foo.new
foo.hello
|
Now let's say we need to add class-level functionality to just this one instance:
class << foo
attr :name, TRUE
def hello
"hello. I'm " + @name + "\n"
end
end
foo.name = "Tom"
foo.hello # -> "hello. I'm Tom\n"
|
We've customized foo without changing the characteristics of Foo,
A module function is a private, singleton method defined in
a module. In effect, it is similar to a
class method, in that it can be called using the
Module.method notation:
Math.sqrt(2) # -> 1.414213562 |
However, because modules can be mixed in to classes, module functions
can also be used without the prefix (that's how all those
Kernel functions are made available to objects):
include Math sqrt(2) # -> 1.414213562 |
Use module_function to make a method a module function.
module Test
def thing
# ...
end
module_function :thing
end
|
Modules are collections of methods and constants. They cannot generate instances. Classes may generate instances (objects), and have per-instance state (instance variables).
Modules may be mixed in to classes and other modules. The mixed-in module's constants and methods blend into that class's own, augmenting the class's functionality. Classes, however, cannot be mixed in to anything.
A class may inherit from another class, but not from a module.
A module may not inherit from anything.
No. However, a module may be included in a class or another module to mimic multiple inheritance (the mixin facility).
This does not generate a subclass (which would require inheritance), but
does generate an is_a? relationship between the class and the
module.
The module Comparable provides a variety of comparison
operators (<, <=, >, between? and so on). It defines
these in terms of calls to the general comparison method,
<=>. However, it does not itself define
<=>.
Say you want to create a class where comparisons are based on the number of legs an animal has:
class MyClass
include Comparable
attr :legs
def initialize(name, legs)
@name, @legs = name, legs
end
def <=>(o)
return @legs <=> o.legs
end
end
c = MyClass.new('cat', 4)
s = MyClass.new('snake', 0)
p = MyClass.new('parrot', 2)
c < s # -> false
s < c # -> true
p >= s # -> true
p.between?(s, c) # -> true
[p, s, c].sort # -> [snake, parrot, cat]
|
All MyClass must do is define its own semantics for the
operator <=>, and mix-in the Comparable
module. Comparable's methods now become indistinguishable from
MyClass's and your class suddenly sprouts new
functionality. And because the same Comparable module is used
my many classes, your new class will share a consistent and well
understood semantic.
You can define a class method in the class definition, and you can define a class method at the top level?
class Demo def Demo.classMethod end end def Demo.anotherClassMethod end |
There is only one significant difference between the two. In the
class definition you can refer to the class's constants directly, as
the constants are within scope. At the top level, you have to use the
Class::CONST notation.
load and require?
load will load and execute a Ruby program (*.rb).
require loads Ruby programs as well, but will also load binary
Ruby extension modules (shared libraries or DLLs). In addition,
require ensures that a feature is never loaded more than
once.
include and extend?
include mixes a module into a class or another module. Methods
from that the module are called function-style (without a receiver).
extend is used to include a module in an object(instance).
Methods in the module become methods in the object.
self mean?
self is the currently executing receiver--the object to which
a method is applied. A function-style method call implies
self as the receiver.
Say file1 contains:
var1 = 99 |
and some other file loads it in:
require 'file1' puts var1 Produces: prog.rb:2: undefined local variable or method `var1' for #<Object:0x401c1ce0> (NameError) |
You get an error because load and require arrange
for local variables to be stored into a separate, anonymous namespace,
effectively discarding them. This is designed to protect your code
from being polluted.