Implementing Class and Singleton Methods

Problem

You want to associate a new method with a class (as opposed to the instances of that class), or with a particular object (as opposed to other instances of the same class).

Solution

To define a class method, prefix the method name with the class name in the method definition. You can do this inside or outside of the class definition.

The Regexp.is_valid? method, defined below, checks whether a string can be compiled into a regular expression. It doesn't make sense to call it on an already instantiated Regexp, but it's clearly related functionality, so it belongs in the Regexp class (assuming you don't mind adding a method to a core Ruby class).

	class Regexp
	 def Regexp.is_valid?(str)
	 begin
	 compile(str)
	 valid = true
	 rescue RegexpError
	 valid = false
	 end
	 end
	end
	Regexp.is_valid? "The horror!" # => true
	Regexp.is_valid? "The)horror!" # => false

Here's a Fixnum.random method that generates a random number in a specified range:

	def Fixnum.random(min, max)
	 raise ArgumentError, "min > max" if min > max
	 return min + rand(max-min+1)
	end
	Fixnum.random(10, 20) # => 13
	Fixnum.random(-5, 0) # => -5
	Fixnum.random(10, 10) # => 10
	Fixnum.random(20, 10)
	# ArgumentError: min > max

To define a method on one particular other object, prefix the method name with the variable name when you define the method:

	company_name = 'Homegrown Software'
	def company_name.legalese
	 return "#{self} is a registered trademark of ConglomCo International."
	end

	company_name.legalese
	# => "Homegrown Software is a registered trademark of ConglomCo International."
	'Some Other Company'.legalese
	# NoMethodError: undefined method 'legalese' for "Some Other Company":String

 

Discussion

In Ruby, a singleton method is a method defined on one specific object, and not available to other instances of the same class. This is kind of analagous to the Singleton pattern, in which all access to a certain class goes through a single instance, but the name is more confusing than helpful.

Class methods are actually a special case of singleton methods. The object on which you define a new method is the Class object itself.

Some common types of class methods are listed here, along with illustrative examples taken from Ruby's standard library:

  • Methods that instantiate objects, and methods for retrieving an object that implements the Singleton pattern. Examples: Regexp.compile, Date.parse, Dir. open, and Marshal.load (which can instantiate objects of many different types). Ruby's standard constructor, the new method, is another example.
  • Utility or helper methods that use logic associated with a class, but don't require an instance of that class to operate. Examples: Regexp.escape, Dir.entries, File.basename.
  • Accessors for class-level or Singleton data structures. Examples: THRead.current, Struct.members, Dir.pwd.
  • Methods that implicitly operate on an object that implements the Singleton pattern. Examples: Dir.chdir, GC.disable and GC.enable, and all the methods of Process.

When you define a singleton method on an object other than a class, it's usually to redefine an existing method for a particular object, rather than to define a brand new method. This behavior is common in frameworks, such as GUIs, where each individual object has customized behavior. Singleton method definition is a cheap substitute for subclassing when you only need to customize the behavior of a single object:

	class Button
	 #A stub method to be overridden by subclasses or individual Button objects
	 def pushed
	 end
	end

	button_a = Button.new
	def button_a.pushed
	 puts "You pushed me! I'm offended!"
	end

	button_b = Button.new
	def button_b.pushed
	 puts "You pushed me; that's okay."
	end
	
	Button.new.pushed
	#

	button_a.pushed
	# You pushed me! I'm offended!
	
	button_b.pushed
	# You pushed me; that's okay.

When you define a method on a particular object, Ruby acts behind the scenes to transform the object into an anonymous subclass of its former class. This new class is the one that actually defines the new method or overrides the methods of its superclass.


Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net