This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
class << self idiom in Ruby
Can someone please explain class << self to me?
I would like to know what does class << self statement mean in a model class? And how does the statement inside it differ from those outside from it. For example:
class Post < ActiveRecord::Base
class << self
def search(q)
# search from DB
end
end
def search2(qq)
# search from DB
end
end
What does class << self mean?
What are the differences between method search(q) and search2(qq) ?
That is the same as
class Post < ActiveRecord::Base
def self.search(q)
# Class Level Method
# search from DB
end
def search2(qq)
# Instance Level Method
# search from DB
end
end
Class methods work on the class (e.g. Post), instance methods works on instances of that class (e.g. Post.new)
Some people like the class << self; code; end; way because it keeps all class level methods in a nice block and in one place.
Others like to prefix each method with self. to explicitly know that is a class method not an instance method. It's a matter of style and how you code. If you put all class methods in a block like class << self, and this block is long enough, the class << self line might be out of your editor view making it difficult to know that you are in the class instance block.
On the other hand, prefixing each method with self. and intermixing those with instance methods is also a bad idea, how do you know all the class methods while reading your code.
Pick an idiom which you prefer for your own code base but if you work on an open source project or you collaborate on someone else's code, use their code formatting rule.
It creates class methods as opposed to instance methods. It's the same as doing def self.search(q). Those two methods would be called like:
Post.search(q)
Post.new.search(qq)
search2 is an instance-method while search is a class-method. The class << self syntax enables you to group class methods below. There are three ways of defining class methods in Ruby:
class MyClass
def self.method
# do sth.
end
def MyClass.method2
# do sth.
end
class << self
def method3
# do sth.
end
def another_class_method
# do sth.
end
end
end
Class-methods are called on a class, not on an instance. It is personal preference which of the three idioms you want to use. I prefer def self.method for no particular reason.
Related
I want to define methods dynamically using an array of strings.
Here is a simple piece of code that should achieve that.
class SomeClass
attr_accessor :my_array
def initialize(user, record)
#my_array=[]
end
my_array.each do |element|
alias_method "#{element}?".to_sym, :awesome_method
end
def awesome_method
puts 'awesome'
end
end
When I instantiate this class in the console, I get the following error
NoMethodError (undefined method `each' for nil:NilClass)
What is wrong with this code and how to make it work. any help highly appreciated :)
Edit 1:
What I ultimately want to achieve is to inherit from SomeClass and override my_array in the child class to dynamically define methods with its attributes like so
class OtherClass < SomeClass
my_array = %w[method1 method2 method3]
# Some mechanism to over write my_array.
end
And then use self.inherited to dynamically define methods in child class.
Is there a good way to achieve this?
In your code, you use an instance variable (#my_array) and an attr_accessor over it, and then try to access my_array from class level (that is, from the body of the class definition, outside of any methods). But instance variables only exist at instance level, so it is not available in the class scope.
One solution (the natural one, and the one which you would probably use in other languages) is to use a class variable: ##my_array. But class variables in ruby are a little problematic, so the best solution would be to make use of class instance variables, like that:
class SomeClass
class << self
attr_accessor :my_array
end
#my_array=[]
def initialize(user, record)
end
#my_array.each do |element|
alias_method "#{element}?".to_sym, :awesome_method
end
def awesome_method
puts 'awesome'
end
end
The syntax is a little tricky, so, if you look that up and it still doesn't makes sense, try just reading about scopes and using a regular class variable with ##.
Edit:
Ok, so, after your edit, it became more clear what you are trying to accomplish. A full working example is like follows:
class SomeClass
class << self
attr_accessor :my_array
end
#my_array=[]
def awesome_method
puts 'awesome'
end
def self.build!
#my_array.each do |element|
self.define_method("#{element}?".to_sym){ awesome_method }
end
end
end
class ChildClass < SomeClass
#my_array = %w[test little_test]
self.build!
end
child_instance = ChildClass.new
child_instance.test?
>> awesome
child_instance.little_test?
>> awesome
So, I've made some tweaks on SomeClass:
It does not need an initialize method
I tried to use the inherited hook for this problem. It won't ever work, because this hook is called as soon as "ChildClass < SomeClass" is written, and this must be before you can define something like #my_array = %w[test little_test]. So, I have added a self.build! method that must be called in the child instances so that they build their methods from my_array. This is inevitable, but I think it is also good, because it makes more explicit in the subclasses that you are doing something interesting there.
I think you want "define_method", not "alias_method".
awesome_method in passed in a block, which is ruby's way of doing functional programming.
With that done, ChildClass inherits from SomeClass, and it's instances have the dynamically created methods 'test?' and 'little_test?'.
You need to change my_array to class level accessible, in my case class constant.
class SomeClass
DYNAMIC_METHOD_NAMES = %w(method_a method_b method_C).freeze
def initialize(user, record)
end
DYNAMIC_METHOD_NAMES.each do |element|
alias_method "#{element}?".to_sym, :awesome_method
end
def awesome_method
puts 'awesome'
end
end
This Ruby Style Guide tells that is better using self.method_name instead of class method_name. But Why?
class TestClass
# bad
class << self
def first_method
# body omitted
end
def second_method_etc
# body omitted
end
end
# good
def self.first_method
# body omitted
end
def self.second_method_etc
# body omitted
end
end
Are there performance issues?
class << self is good at keeping all of your class methods in the same block. If methods are being added in def self.method form then there's no guarantee (other than convention and wishful thinking) that there won't be an extra class method tucked away later in the file.
def self.method is good at explicitly stating that a method is a class method, whereas with class << self you have to go and find the container yourself.
Which of these is more important to you is a subjective decision, and also depends on things like how many other people are working on the code and what their preferences are.
Generally, class << self is used in metaprogramming to set the class as self for a prolonged period of time. If I'm trying to write 10 methods, I would use it like so:
METHOD_APPENDICES = [1...10]
class << self
METHOD_APPENDICES.each do |n|
define_method("method#{n}") { n }
end
end
This would create 10 methods (method1, method2, method3, etc.) that would just return the number. I would use class << self for clarity in this case because in metaprogramming self is crucial. Littering self. inside there would actually make things less readable.
If you're just defining class methods normally, stick to self.class_method_name because more people are likely to understand it. No need to bring in meta-syntax unless you expect your audience to understand it.
As noted above, both styles seem to be equivalent, however using class << self allows one to mark class methods as private or protected. For example:
class UsingDefSelf
def self.a; 'public class method'; end
private
def self.b; 'public class method!'; end
end
class UsingSingletonClass
class << self
def a; 'public class method'; end
private
def b; 'private class method'; end
end
end
private only affects instance methods. Using the singleton class, we are defining instance methods of that class, which turn into class methods of the containing class!
We can also mark class methods as private with def self:
class UsingDefSelf
def self.a; 'private class method'; end
def self.b; 'private class method!'; end
private_class_method :a, :b
# In Ruby 2.1 there is an alternative syntax
private_class_method def self.c; 'private class method!'; end
end
But we cannot mark them as protected, there is no protected_class_method. (However, since class is the only instance of its singletonclass, private class method and protected class methods are almost the same except their calling syntax is different.)
Also it is less easier than using class << self to mark private class methods, since you have to list all method names in private_class_method or prefix private_class_method to every private class method definition.
I assume that they think self.* is better because you can say for sure, it's a class or instance method, without having to scroll up and seaching this class << self string.
Whichever you want. Both are very clear for what you do. But I think of some recommendations for this.
When there're only one class method to define, Use def self.xxx. Because for defining only one method, increasing indent level probably become cluttering.
When there're more than one class method to define, Use class << self. Because writing def self.xxx, def self.yyy and def self.zzz is certainly repetition. Create a section for these methods.
When all methods in a class are class method, you can use module with module_function instead of class. This let you define module functions just use def xxx.
So far the question and answers only discuss these two options:
class MyClass
def self.method_name
..
end
end
class MyClass
class << self
def method_name
..
end
end
end
There's a third option to consider for class methods:
class MyClass
def MyClass.method_name
..
end
end
It's not popular and is more verbose, but it's the most explicit option.
It's also less confusing if you mix up self behaviour between Python and Ruby.
I am using Ruby 1.9.2 and the Ruby on Rails v3.2.2 gem. I am trying to learn Metaprogramming "the right way" and at this time I am aliasing an instance method in the included do ... end block provided by the RoR ActiveSupport::Concern module:
module MyModule
extend ActiveSupport::Concern
included do
# Builds the instance method name.
my_method_name = build_method_name.to_sym # => :my_method
# Defines the :my_method instance method in the including class of MyModule.
define_singleton_method(my_method_name) do |*args|
# ...
end
# Aliases the :my_method instance method in the including class of MyModule.
singleton_class = class << self; self end
singleton_class.send(:alias_method, :my_new_method, my_method_name)
end
end
"Newbiely" speaking, with a search on the Web I came up with the singleton_class = class << self; self end statement and I used that (instead of the class << self ... end block) in order to scope the my_method_name variable, making the aliasing generated dynamically.
I would like to understand exactly why and how the singleton_class works in the above code and if there is a better way (maybe, a more maintainable and performant one) to implement the same (aliasing, defining the singleton method and so on), but "the right way" since I think it isn't so.
I recommend Yehuda Katz's post on metaprogamming on Ruby's self. Here's my humble summary in response to your question:
In Ruby, all objects have a singleton class (also known as metaclass). Objects inherit first from their singleton class invisibly, then from their explicit class. Ruby classes themselves have their own singleton classes since classes are objects as well. The class << idiom is simply Ruby's syntax for accessing the scope of an object's singleton class.
class Person
class << self
# self in this scope is Person's singleton class
end
end
person = Person.new
person_singleton_class = class << person; self; end
Your version of Rails actually provides singleton_class as a shortcut. Since singleton_class is an available method, you don't need to assign it to a variable in the expression singleton_class = class << self; self end:
Person.singleton_class
person = Person.new
person.singleton_class
Since a class inherits directly from its singleton class, this is where we want to add class methods dynamically when metaprogramming. Ruby provides a few ways to open up the scope of an object while maintaining access to the surrounding scope: class_eval and instance_eval. There are subtle differences in the way these behave (Yehuda's post explains this), but you may use either to enter the scope of your singleton class, resolve methods on the singleton class as self and still have access to my_method_name from the surrounding scope.
All that said, you could make a few small changes to your module:
module MyModule
extend ActiveSupport::Concern
included do
# Builds the instance method name.
my_method_name = build_method_name.to_sym # => :my_method
# Defines the :my_method instance method in the including class of MyModule.
define_singleton_method(my_method_name) do |*args|
# ...
end
singleton_class.class_eval do
# method resolution in scope of singleton class
alias_method :my_new_method, my_method_name
end
end
end
I have the following code:
class MyClass
module MyModule
class << self
attr_accessor :first_name
def myfunction
MyModule.first_name = "Nathan"
end
end
end
end
When I call the method myfunction like so, it works fine:
> me = MyClass::MyModule.myfunction
=> "Nathan"
> me
=> "Nathan"
But if I removed the class << self and add a self. prefix to myfunction, it doesn't work.
For example:
class MyClass
module MyModule
attr_accessor :first_name
def self.myfunction
MyModule.first_name = "Nathan"
end
end
end
> me = MyClass::MyModule.myfunction
NoMethodError: undefined method `first_name=' for MyClass::MyModule:Module
I'm trying to understand the class << self method. I thought it was a way add the self. prefix to the all the methods inside of it, but if that was true, why doesn't it work if I remove it and prefix each method with self. manually?
Thanks in advance for your help.
This is because your attr_accessor :first_name is also wrapped by the class << self.
To do it the way you suggest, you can use mattr_accessor like so:
require 'active_support'
class MyClass
module MyModule
mattr_accessor :first_name
def self.myfunction
MyModule.first_name = "Nathan"
end
end
end
To better understand how you can achieve what you want, take a look at the following example:
module PrintingModule
def self.included(object)
object.extend(ClassMethods)
end
module ClassMethods
def class_method_of_class
puts "I am class #{self.name}"
end
end
def instance_method_of_class
puts "My name is: #{#name}"
end
class << self
def static_module_method
puts "Printer version 1.0"
end
end
end
class SomeObject
include PrintingModule
def initialize(name)
#name = name
end
end
object = SomeObject.new("Something")
object.instance_method_of_class
SomeObject.class_method_of_class
PrintingModule.static_module_method
I hope it's more clear now, note that this is just one of possible way (there are others)
UPDATE:
I'll try to be more specific. When you define instance/singleton methods on module, what you are really doing is that you are defining instance methods of class which will include that module and on the other hand, class methods defined on module will become class methods of that module. The second think to know is that attr_accessor creates instance method for getter and setter of the given parameter.
Now to answer one part of your question, in the first example you are creating 3 class methods on module's class. In the second one, you are creating 1 class method where you are trying to access another class method (setter), but your getters and setters are defined as instance methods = they will become instance of method of class which will include your module, you cannot get to them this way = you have no access to your getters and setters.
As for explanation of self, well I'm not that skilled, but as far as I know, when you use "class << self" you are opening eigenclass (each object has it's own anynonymous one) of the object (note that Class, modules or instances of classes are of course objects too) where you are defining instance methods. Class method of object in Ruby = instance method of the eigenclass of the object. So you can do this for example:
text = "something"
class << text
def say_hi
puts "Hi!"
end
end
text.say_hi
When you create instance of class (String in that example), that instance gets it's own unique anonymous class which is subclass of that Class. In the example, you have defined instance method on the eigenclass of the anonymous subclass of String class. So you can use method "say_hi" on the text object but not on the String class. So "class << self" is opening those eigenclasses.
On the other hand, "self" alone just represents an object in the current context, which means the same in some scenarios (for example yours). As for self.included method, it is just a callback method which gets called when the module is included in the class with a parameter representing the object (here class SomeObject).
I hope that I have answered at least part of your question.
More information here:
Difference between 'self.method_name' and 'class << self' in Ruby
Background here.
In the above link, the following example is given:
class << self
def by_author(author)
where(:author_id => author.id)
end
end
Aside from that syntax being foreign to a beginner like me — I had always thought class methods were defined with def self.my_class_method — where can I find documentation about class methods in Ruby on Rails?
As far as I know, class methods are always called on the class itself (MyClass.my_class_method), but if class methods in Rails are chainable, it seems as though something else must be going on here!
Edit:
I suppose I sort of cheated by making that comment about the syntax for class methods. I'm really asking how Rails makes a class method chainable — I understand how method chaining works, but not how Rails can allow you to chain class methods without actually returning the class object itself after each "link" in the chain.
Class methods in Ruby are really just members of the singleton class, and doing class << self involves opening the singleton class directly and adding to it, removing the need to declare it in each method definition.
This article on Ruby singletons does a good job explaining.
As far as class methods being chainable, that isn't something specific to class methods, the second method call is simply called on the object returned from the first. For example:
bar = foo.do_something.do_more
is equivalent to:
tmp = foo.do_something
bar = tmp.do_more
In Rails, this chainability is most often used for building SQL queries (e.g., with where or order, etc.). This is achieved because each of these methods returns an ActiveRecord Relation.
The reason
foo.scoped.my_foo_class_method
works is because of ActiveRecord::Relation#method_missing doing the following:
elsif #klass.respond_to?(method)
scoping { #klass.send(method, *args, &block) }
Which checks if the ActiveRecord class responds to the method called, and if so, calls that.
Having class << self is also another way to define your methods so that you do not have to call "def self.my_method" or "def MyClass.my_method" for every single method that you are defining as a class method. Instead of calling
def self.my_method1
end
def self.my_method2
end
class << self
def my_method1
end
def my_method2
end
end
Cheers!
The following two bits of code are equivalent.
Using self.method:
class Hello
def self.world
puts "Hello, World!"
end
end
Using class << self:
class Hello
class << self
def world
puts "Hello, World!"
end
end
end
The only difference is readability, as well as the ease in refactoring.
The class << self technique is often used when metaprogramming.
There is another thread that explains this. class << self vs self.method with Ruby: what's better?