This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
class << self idiom in Ruby
I was wondering what this code is doing. I don't understated this one line. I know what attr_accessor is.
class User
class << self; attr_accessor :base_uri end
....
....
...
You will see class << self used often in Ruby. The easiest way to understand what it does is to think of it as (almost) equivalent to this:
class Abc
self.attr_accessor ...
end
Which is basically the same as this:
Abc.class.attr_accessor ...
But you really can't do either of those because:
> Abc.class.attr_accessor :blah
NoMethodError: private method `attr_accessor' called for Class:Class
So to get around it you'd have to do:
> Abc.class.send(:attr_accessor, :blah)
Or:
class Abc
self.send(:attr_accessor, :blah)
end
That's where the << self construct comes in since it gives you access to these private methods. You are basically operating directly in "self-space".
Similarly when you see:
class Abc
class << self
def foo
end
end
end
It's just the same as saying:
class Abc
def self.foo
end
end
Which will define a class method, just like the code in your question will define a class-level attr_accessor.
EDIT
As for a less complicated way - Ruby doesn't really by default have a method that is able to create class-level attr_accessors. That's why you have to use the << self trick.
But Rails does define a method that does something similar without having to use << self. In Rails you have cattr_accessor:
class Abc
cattr_accessor :blah
end
Abc.blah = 123
Abc.blah
>> 123
This let define an instance variable in the class context.
See the code:
class User
class << self; attr_accessor :base_uri end
#base_uri = "aaa";
end
p User.base_uri # will output "aaa"
Related
I would like to access a class' name in its superclass MySuperclass' self.inherited method. It works fine for concrete classes as defined by class Foo < MySuperclass; end but it fails when using anonymous classes. I tend to avoid creating (class-)constants in tests; I would like it to work with anonymous classes.
Given the following code:
class MySuperclass
def self.inherited(subclass)
super
# work with subclass' name
end
end
klass = Class.new(MySuperclass) do
def self.name
'FooBar'
end
end
klass#name will still be nil when MySuperclass.inherited is called as that will be before Class.new yields to its block and defines its methods.
I understand a class gets its name when it's assigned to a constant, but is there a way to set Class#name "early" without creating a constant?
I prepared a more verbose code example with failing tests to illustrate what's expected.
Probably #yield has taken place after the ::inherited is called, I saw the similar behaviour with class definition. However, you can avoid it by using ::klass singleton method instead of ::inherited callback.
def self.klass
#klass ||= (self.name || self.to_s).gsub(/Builder\z/, '')
end
I am trying to understand the benefit of being able to refer to an anonymous class by a name you have assigned to it after it has been created. I thought I might be able to move the conversation along by providing some code that you could look at and then tell us what you'd like to do differently:
class MySuperclass
def self.inherited(subclass)
# Create a class method for the subclass
subclass.instance_eval do
def sub_class() puts "sub_class here" end
end
# Create an instance method for the subclass
subclass.class_eval do
def sub_instance() puts "sub_instance here" end
end
end
end
klass = Class.new(MySuperclass) do
def self.name=(name)
#name = Object.const_set(name, self)
end
def self.name
#name
end
end
klass.sub_class #=> "sub_class here"
klass.new.sub_instance #=> "sub_instance here"
klass.name = 'Fido' #=> "Fido"
kn = klass.name #=> Fido
kn.sub_class #=> "sub_class here"
kn.new.sub_instance #=> "sub_instance here"
klass.name = 'Woof' #=> "Woof"
kn = klass.name #=> Fido (cannot change)
There is no way in pure Ruby to set a class name without assigning it to a constant.
If you're using MRI and want to write yourself a very small C extension, it would look something like this:
VALUE
force_class_name (VALUE klass, VALUE symbol_name)
{
rb_name_class(klass, SYM2ID(symbol_name));
return klass;
}
void
Init_my_extension ()
{
rb_define_method(rb_cClass, "force_class_name", force_class_name, 1);
}
This is a very heavy approach to the problem. Even if it works it won't be guaranteed to work across various versions of ruby, since it relies on the non-API C function rb_name_class. I'm also not sure what the behavior will be once Ruby gets around to running its own class-naming hooks afterward.
The code snippet for your use case would look like this:
require 'my_extension'
class MySuperclass
def self.inherited(subclass)
super
subclass.force_class_name(:FooBar)
# work with subclass' name
end
end
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why isn't the eigenclass equivalent to self.class, when it looks so similar?
class << self idiom in Ruby
I have this class:
class Player < ActiveRecord::Base
before_save :set_slug
def remains
((end_date - Date.today) + 1).to_i
end
def self.url
"Our_link_#{slug}"
end
class << self
def load_track_lists
#do somthing
end
end
end
and I understand the class and instance methods but the
class << self
def load_track_lists
#do somthing
end
end
is really confusing. What is it and how does it differ from the prior two methods?
The end result is basically the same as if it had been defined as
def self.load_track_lists
#do somthing
end
There are subtle differences between the two methods if you're doing more than just defining methods in the class << self block, as described in the linked question, but effectively you're "opening up" the current class to define class level methods in it.
It doesn't differ from the self.url method. It's basically a container that allows you to put multiple methods without having to put self. in front of the method name. Probably not useful in the example but can be quite clean for other classes.
IMO it's a developer's preference
class << Awesomeness
What is this << for? I searched, but the results only tell me about string concatenation...
While it's true that class << something is the syntax for a singleton class, as someone else said, it's most often used to define class methods within a class definition. But these two usages are consistent. Here's how.
Ruby lets you add methods to any particular instance by doing this:
class << someinstance
def foo
"Hello."
end
end
This adds a method foo to someinstance, not to its class but to that one particular instance. (Actually, foo is added to the instance's "singleton class," but that's more or less an implementation quirk.) After the above code executes, you can send method foo to someinstance:
someinstance.foo => "Hello."
but you can't send foo to other instances of the same class. That's what << is nominally for. But people more commonly use this feature for syntactic gymnastics like this:
class Thing
def do_something
end
class << self
def foo
puts "I am #{self}"
end
end
end
When this code -- this class definition -- executes, what is self? It's the class Thing. Which means class << self is the same as saying "add the following methods to class Thing." That is, foo is a class method. After the above completes, you can do this:
t = Thing.new
t.do_something => does something
t.class.foo => "I am Thing"
t.foo => NoMethodError: undefined method `foo'
And when you think about what << is doing, it all makes sense. It's a way to append to a particular instance, and in the common case, the instance being appended to is a class, so the methods within the block become class methods.
In short, it's a terse way to create class methods within a class definition block. Another way would be to do this:
class Thing
def self.foo
# ...
end
end
Same thing. Your example is actually a syntax error, but if you understand how << is used with instances and the class keyword, you'll know how to correct it.
<< is the syntax for "Singleton class definition". Here is an example of where/how it is "typically" used.
In a = "abc"; a << "xyz" it is the syntax for "appending data" (to string, array etc.)
If you want inheritance (based on your question title), you want a single <:
class Awesome < ParentAwesomeness
The code you provide isn't valid ruby:
class Awesomeness
end
class Awesome << Awesomeness
end
SyntaxError: (irb):3: syntax error, unexpected tLSHFT, expecting '<' or ';' or '\n'
I am a Ruby starter. I found both of these are quite similar (in output), but i couldn't understand the difference in the below context. For example, I have a class
class Say
def self.hello
puts "hello"
end
end
and can be extended like this
class << Say
def hi
puts "hi"
end
end
and also like this
Say.class_eval do
def self.bye
puts "bye"
end
end
When should I use << and when class_eval?
class_eval doesn't really have anything to do with class << className.
A.class_eval do
...
end
is equivalent to
class A
...
end
with a few differences. class_eval uses a block (or a string, but ignoring that for the moment) which means it closes over the containing lexical scope. In other words you can use local variables from the surrounding scope. The common class block introduces a brand new scope. Likewise you can create the block and pass it to many different class_eval's, and the body of the block will be executed in the context of the class you are calling class_eval on.
class << className opens the singleton class of className, allowing you to define class methods.
class << A
def foo
...
end
end
Is the same as
def A.foo
...
end
Note that they are oly class methods if A happens to be a class (almost) all objects in ruby have singleton classes and you can define methods for them using either of those two syntaxes. The advantage of class << obj is mainly if you're defining many singleton methods in one go.
As already said class_eval has really not much to do with
class <<self
even if they seem to do the same thing in your example (while the effect is similar it does not do the same, there are subtle differences).
Here is another example where the usage of the second form is far more clearer:
class A
end
a = A.new
b = A.new
class <<b
def say_hi
puts "Hi !"
end
end
b.say_hi # will print "Hi !"
a.say_hi # will raise an undefined method
a and b are both objects of the same class A but we added a method to the metaclass of b so the method say_hi is only available to the b object.
Given a class like this:
class B
class << self
attr_accessor :var
end
end
Suppose I can't modify the original source code of class B. How might I go about removing the setter on the class variable var? I've tried using something like B.send("unset_method", "var="), but that doesn't work (nor does remove_method, or overwriting that method with a var= method that doesn't do anything). Any ideas?
Try:
class B
class << self
undef var=
end
end
You may want to use remove_method instead:
class B
class << self
remove_method :var=
end
end
To see the differences, go to:
http://www.nach-vorne.de/2008/2/28/undef_method-remove_method/
class <<B ; remove_method :var= ; end