Mixing in Class Methods

Credit: Phil Tomson

Problem

You want to mix class methods into a class, instead of mixing in instance methods.

Solution

The simplest way to accomplish this is to call extend on the class object, as seen in the Discussion of Recipe 9.2. Just as you can use extend to add singleton methods to an object, you can use it to add class methods to a class. But that's not always the best option. Your users may not know that your module provides or even requires some class methods, so they might not extend their class when they should. How can you make an include statement mix in class methods as well?

To begin, within your module, define a submodule called ClassMethods,[3]which contains the methods you want to mix into the class:

[3] The name ClassMethods has no special meaning within Ruby: technically, you can call your submodule whatever you want. But the Ruby community has standardized on ClassMethods as the name of this submodule, and it's used in many Ruby libraries, so you should use it too.

	module MyLib
	 module ClassMethods
	 def class_method
	 puts "This method was first defined in MyLib::ClassMethods"
	 end
	 end
	end

To make this code work, we must also define the included callback method within the MyLib module. This method is called every time a module is included in the class, and it's passed the class object in which our module is being included. Within the callback method, we extend that class object with our ClassMethods module, making all of its instance methods into class methods. Continuing the example:

	module MyLib
	 def self.included(receiver)
	 puts "MyLib is being included in #{receiver}!"
	 receiver.extend(ClassMethods)
	 end
	end

Now we can include our MyLib module in a class, and get the contents of ClassMethods mixed in as genuine class methods:

	class MyClass
	 include MyLib
	end
	# MyLib is being included in MyClass!

	MyClass.class_method
	# This method was first defined in MyLib::ClassMethods

 

Discussion

Module#included is a callback method that is automatically called during the inclusion of a module into a class. The default included implementation is an empty method. In the example, MyLib overrides it to extend the class that's including the MyLib module with the contents of the MyLib::ClassMethods submodule.

The Object#extend method takes a Module object as a parameter. It mixes all the methods defined in the module into the receiving object. Since classes are themselves objects, and the singleton methods of a Class object are just its class methods, calling extend on a class object fills it up with new class methods.

See Also

  • Recipe 7.11, "Coupling Systems Loosely with Callbacks," covers callbacks in general and shows how to write your own
  • Recipe 10.6, "Listening for Changes to a Class," covers Ruby's other class and module callback methods


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