Metaclass/Singleton class question.

I understand that (class << self; self; end) returns the singelton class
of object that is calling it but why would use that instead of self <<
MyClass ...?

For example, arent these all equivalent?

class << String
  def foo
    puts "foo"
  end
end

class String
  class << self
    def foo
      puts "foo"
    end
  end
end

class String
  (class << self; self; end).module_eval do
     def foo
       puts "foo"
     end
  end
end

So why would you use the more obscure (class << self; self; end)
technique? Can someone please explain.

I understand that (class << self; self; end) returns the singelton
class
of object that is calling it but why would use that instead of self <<
MyClass ...?

For example, arent these all equivalent?

class << String
def foo
   puts "foo"
end
end

class String
class << self
   def foo
     puts "foo"
   end
end
end

class String
(class << self; self; end).module_eval do
    def foo
      puts "foo"
    end
end
end

So why would you use the more obscure (class << self; self; end)
technique? Can someone please explain.

if self isn't a class for example

class Object
   def meta
     (class << self; self; end)
   end
end

x = "123"
x.meta.module_eval do
   def foo
     puts "foo"
   end
end

x.foo

you could of course have just done

def x.foo
   puts "foo"
end

but sometimes you want to more than just add a method.

Fred