Ruby classes and << Syntax

I have written a simple snippet of code and would appreciate any help with understanding what's really going on.

### Creating Basic Class
class Person # Same as: class Person < Object
   attr_accessor :firstname
   attr_accessor :lastname

   def initialize(firstname, lastname)
     @firstname, @lastname = firstname, lastname
   end

   def fullname
     @firstname + ' ' + @lastname
   end
end

### Create two instances of class Person
john = Person.new('John', 'Doe')
john.firstname # => "John"
john.lastname # => "Doe"
john.to_s # => "#<Person:0x356678>"

jack = Person.new('Jack', 'Stone')
jack.firstname # => "Jack"
jack.lastname # => "Stone"
jack.to_s # => "#<Person:0x3512f4>"

class Person
   def to_s
     'Person: ' + fullname
   end
end

john.to_s # => "Person: John Doe"
jack.to_s # => "Person: Jack Stone"
### Everything as expected until here...

### Now the interesing part:
class <<Person
   def birthday
     '2008-05-16'
   end
end

### NOT EXPECTED:
john.birthday # => NoMethodError: undefined method `birthday' for #<Person ...>
jack.birthday # => NoMethodError: undefined method `birthday' for #<Person ...>

frank = Person.new('Frank', 'New') # => Try with new instance
frank.birthday # => NoMethodError: undefined method `birthday' for #<Person ...>

### So basically my question is: What does the 'class <<Person' Statement really do?

Thank you very much!
Christoph Schiessl

You are defining a class method and not a class instance method. Do this...

class Person
  def birthday
    '2008-05-16'
  end
end

Todd

···

On Fri, May 16, 2008 at 11:54 AM, Christoph Schiessl <c.schiessl@gmx.net> wrote:

I have written a simple snippet of code and would appreciate any help with
understanding what's really going on.

### Creating Basic Class
class Person # Same as: class Person < Object
attr_accessor :firstname
attr_accessor :lastname

def initialize(firstname, lastname)
   @firstname, @lastname = firstname, lastname
end

def fullname
   @firstname + ' ' + @lastname
end
end

### Create two instances of class Person
john = Person.new('John', 'Doe')
john.firstname # => "John"
john.lastname # => "Doe"
john.to_s # => "#<Person:0x356678>"

jack = Person.new('Jack', 'Stone')
jack.firstname # => "Jack"
jack.lastname # => "Stone"
jack.to_s # => "#<Person:0x3512f4>"

class Person
def to_s
   'Person: ' + fullname
end
end

john.to_s # => "Person: John Doe"
jack.to_s # => "Person: Jack Stone"
### Everything as expected until here...

### Now the interesing part:
class <<Person
def birthday
   '2008-05-16'
end
end

Which means:

class <<Person
   def birthday
     '2008-05-16'
   end
end

Is EXACTLY the same as:

class Person
   def self.birthday
     '2008-05-16'
   end
end

Or:

class Person
   class <<self
     def birthday
       '2008-05-16'
     end
   end
end

Thank you very much!
Christoph Schiessl

···

On May 16, 2008, at 7:10 PM, Todd Benson wrote:

On Fri, May 16, 2008 at 11:54 AM, Christoph Schiessl <c.schiessl@gmx.net > > wrote:

I have written a simple snippet of code and would appreciate any help with
understanding what's really going on.

### Creating Basic Class
class Person # Same as: class Person < Object
attr_accessor :firstname
attr_accessor :lastname

def initialize(firstname, lastname)
  @firstname, @lastname = firstname, lastname
end

def fullname
  @firstname + ' ' + @lastname
end

### Create two instances of class Person
john = Person.new('John', 'Doe')
john.firstname # => "John"
john.lastname # => "Doe"
john.to_s # => "#<Person:0x356678>"

jack = Person.new('Jack', 'Stone')
jack.firstname # => "Jack"
jack.lastname # => "Stone"
jack.to_s # => "#<Person:0x3512f4>"

class Person
def to_s
  'Person: ' + fullname
end

john.to_s # => "Person: John Doe"
jack.to_s # => "Person: Jack Stone"
### Everything as expected until here...

### Now the interesing part:
class <<Person
def birthday
  '2008-05-16'
end

You are defining a class method and not a class instance method. Do this...

class Person
def birthday
   '2008-05-16'
end
end

Todd

Which means:

class <<Person
   def birthday
     '2008-05-16'
   end
end

Is EXACTLY the same as:

class Person
   def self.birthday
     '2008-05-16'
   end
end

Or:

class Person
   class <<self
     def birthday
       '2008-05-16'
     end
   end
end

True, but all 3 are class methods and none will work as you intend.

You would have to call Person.birthday to get a response and everyone
will have the same birthday (what a party!)
Of course you knew that, but some readers might not and I am bored, so
I wrote this.