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
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Abstract class looks in Ruby code like an alien from remote planet Java. I'm trying to collect Ruby tricks which can substitute this unwanted pattern.
Let's take a completely random example:
class AbstractRace < Struct.new(:runner_count)
def go!
runner_count.times.map do |index|
Thread.new do
run(index)
end
end.each(&:join)
end
def run(index)
raise 'To be implemented in derivative classes'
end
end
class RunnerRace < AbstractRace
def run(index)
puts "I am runner number #{index}. I am running"
end
end
class CarRace < AbstractRace
def run(index)
puts "I am car number #{index}. I am accelerating"
end
end
RunnerRace.new(2).go!
CarRace.new(2).go!
How to rewrite it? A possible approach would be using a mixin, like this:
require 'active_support/concern'
module Race
extend ActiveSupport::Concern
def go!
participant_count.times.map do |index|
Thread.new do
run(index)
end
end.each(&:join)
end
module ClassMethods
def configure_race(methods)
[:participant_count, :run].each do |method_symbol|
define_method method_symbol, methods[method_symbol]
end
end
end
end
class RunnerRace < Struct.new(:runner_count)
include Race
configure_race participant_count: ->() { runner_count },
run: ->(index) { puts "I am runner number #{index}. I am running" }
end
class CarRace < Struct.new(:car_count)
include Race
configure_race participant_count: -> { car_count },
run: ->(index) { puts "I am car number #{index}. I am going" }
end
RunnerRace.new(2).go!
CarRace.new(2).go!
What other solutions could be? Is there a common idiom for such case?
Why not just take advantage of the fact that Ruby is a dynamic language?
class Race
attr_reader :participants
def initialize(participants)
#participants = participants
end
def go!
participants.each_with_index.map do |index,participant|
Thread.new do
participant.run(index)
end
end.each(&:join)
end
end
class CarEntry
def run(index)
puts "I am car number #{index}. I am going"
end
end
There is no need for anything running in a 'race' to extend a superclass. All anything in the race must do is be capable of racing i.e having a
run(index)
method that does something.
In ruby I would tend to think of 'AbstractRace' as more of a role for a class to play. Roles are best encapsulated in modules (as you've suggested in your first response).
If you are trying to come up with a general ruby solution, however, I would recommend removing the reference to ActiveSupport::Concern. This module is something that comes from Rails and may not be available in all ruby environments.
There is nothing wrong with what you have written there and I'm not entirely sure what you are unhappy with.
That being said, this is Ruby and there is no need to define the run method on your AbstractRace class. If that's what is bothering you, then just don't do it.
The reason you put it there is to show both yourself and other developers who might be working on the code that a Race should have a run method. It's defining the interface. It definitely is not required though, but it is the "proper" way to make an object oriented class hierarchy.
I think you're missing the point of abstract classes
Languages like Java use abstract classes because they want to:
Collect common code for derived classes in one place (common base class), and
Prevent instantiating this common base class, because it is a base class.
If you wanted to achieve the same goals, you could do this by:
Creating a base class with the common code
Giving it a private constructor:
```
class AbstractRace
private:
def initialize
end
end
```
The other reason people use abstract classes, is the same as interfaces: they want to guarantee that some method exists on a derived class.
Unfortunately, there's no such construction as Ruby; in fact, this is "un-Ruby-like." In Ruby, we rely on "duck typing," which means "if it quacks, it's a duck!" Observe:
class Car
def drive
return 'VROOOM!'
end
end
class Duck
def quack
return 'Quack quack!'
end
end
test_objs = [Car.new, Duck.new]
test_objects.each do |some_obj|
if some_obj.respond_to?(:quack)
puts "#{some_obj} is a duck! #{some_obj.quack}"
else
puts 'Not a duck, sorry.
end
end
This will output something like <Duck:0x123456> is a duck! Quack quack!
This is relying on "duck typing," by checking for the existence of methods before using them. This is the closest idiom in Ruby.
I'm using Ruby's metaprogramming methods creating a bunch of methods within a class. Within the class OmekaItem there are a bunch of methods of this form dc_title and dc_subject, and there are a bunch of methods of this form itm_field1 and itm_field2. I'd like to group those methods better. Ideally, given an instance of the class named item, I'd like call the methods this way:
item.dublin_core.title
item.item_type_metadata.field
and so on. Is there a way to do this?
This question has the code I'm working with.
Would something like the following work for you?
class OmekaItem
class DublinCore
def initialize(omeka_item)
#omeka_item = omeka_item
end
def title
#omeka_item.dc_title
end
def subject
#omeka_item.dc_subject
end
end
class ItemTypeMetadata
def initialize(omeka_item)
#omeka_item = omeka_item
end
def field1
#omeka_item.itm_field1
end
def field2
#omeka_item.itm_field2
end
end
def dublin_core
#dublin_core ||= DublinCore.new(self)
end
def item_type_metadata
#item_type_metadata ||= ItemTypeMetadata.new(self)
end
end
The methods on DublinCore and ItemTypeMetadata could be dynamically generated using define_method as appropriate.
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"
I can't seem to grasp the exact difference between these two "constructs". To my mind, the following small script should output the same thing three times:
class Example
puts self
class << self
puts self
end
instance_eval do
puts self
end
end
However, the output is:
Example
#<Class:Example>
Example
Here's my rationale:
Example is an instance of Class, so self in the class body refers to that;
class << obj sets self to whatever obj is in the given block, which in my case is the instance of Class that is Example (this is where I'm probably wrong);
instance_eval runs the block in the given instance, so, in my case it's pretty much the same as putting the code in the block directly in the class body.
My current guess is that class << self inserts a ghost class between Example and Class and sets self to that, but the output of #<Class:Example> is not confirming that at all.
So what is wrong with my rationale?
class << obj sets self to whatever obj is in the given block, which in my case is the instance of Class that is Example (this is where I'm probably wrong);
No, class << obj opens up the singleton class of obj. As you correctly pointed out, inside of a class declaration, self refers to the class itself, so, in this case, the "inner" self (i.e. the one being passed to puts) refers to the singleton class of Example.
In my opinion, class << self has been one of the most obnoxious bits of syntax in Ruby. People new to the language have little idea what it means, apart from cargo-cult conventions, and even those intimately familiar with the language have only a hazy understanding of what differentiates it from instance_method, as the two do seem to be remarkably similar.
Here's an example of two different ways of defining a class method:
class Example
class << self
def class_def
:class_def
end
end
instance_eval do
def instance_def
:instance_def
end
end
end
You can check that these work by calling the methods:
puts Example.class_def.inspect
# => :class_def
puts Example.instance_def.inspect
# => :instance_def
The difference is when you're dynamically creating methods using define_method since the binding does appear to be incorrect on the instance_eval version:
class Example
class << self
define_method(:class_def) do
:class_def
end
end
instance_eval do
define_method(:instance_def) do
:instance_def
end
end
end
This results in the instance_def method being defined, but not being bound to the class itself:
puts Example.class_def.inspect
# => :class_def
puts Example.instance_def.inspect
# => NoMethodError: undefined method ‘instance_def’ for Example:Class
The only reliable way to create dynamic methods is with class << self. The method instance_def appears to be created and discarded as it doesn't show up in Example.methods even inside that block.
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.