0

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
  ....
....
...
Community
  • 1
  • 1
Bohn
  • 26,091
  • 61
  • 167
  • 254
  • See `singleton_class.instance_eval do` in the second part of http://stackoverflow.com/questions/13850971/why-are-symbols-in-ruby-not-thought-of-as-a-type-of-variable/13861177#13861177 and also http://stackoverflow.com/questions/14428531/ruby-instance-eval-on-a-class-with-attr-accessor/14431130#14431130 – BernardK Jan 31 '13 at 11:00

2 Answers2

5

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
Casper
  • 33,403
  • 4
  • 84
  • 79
1

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"
xdazz
  • 158,678
  • 38
  • 247
  • 274
  • hmm? so if I didn't want to write it like what I posted, was there any less complicated way of writing the same thing? – Bohn Jan 31 '13 at 04:14