RubyTalks.first

Damir Svrtan

Methods you thought were keywords

Keywords?

Reserved words?

Built-in functions?

print()

Builtin function in Python and PHP

But a regular method in Ruby

print everywhere


    print 'Starting our program!'

    class User
      print 'Defining the User class'

      def initialize
        print 'Registering a new user'
      end
    end

But how?

Is it a special global method? NO


  class User
    def initialize(name)
      @name = name
    end

    def name
      @name
    end
  end

  borko = User.new('Borko')

Down to basics

Ancestor chain


  User.ancestors

  => [User, Object, Kernel, BasicObject]

  class Student < User
  end

  Student.ancestors

  => [Student, User, Object, Kernel, BasicObject]

What's a superclass?


  Student.superclass
  => User

  User.superclass
  => Object

  Object.superclass
  => BasicObject

  BasicObject.superclass
  => nil

Ok, so where are borko's methods defined?

In it's class and all the ancestors of course!

one step to the right, then up!

Method lookup is done through the ancestor chain

again, one step to the right, then up!

What about the User class?

borko is an instance of the User class

User class is an instance of Class class

We can also define methods on the instance

Unlike other users, Borko can sing!


  borko  = User.new('Borko')
  zdenko = User.new('Zdenko')

  def borko.sing
    puts "I'm singing in the rain!"
  end

  borko.sing
  => "I'm singing in the rain!"

  zdenko.sing
  => undefined method `sing' for #<User:0x007fc8320bc528>

Eigenclass

The Eigenclass keeps all the singleton methods of an object

Hooks right into the ancestor chain

Does this syntax look familiar?


  def borko.sing
    puts "I'm singing in the rain!"
  end

  class User

    def self.new_from_omniauth(email)
      ...
    end

  end

Ever done sumthin' like this?


  class User

    class << self # What is self?
      # Defining the method on the eigenclass of self
      def new_from_omniauth(email)
        ...
      end
    end

  end

Or like this?


  class User

    class << self
      def new_from_omniauth(email)
        ...
      end
    end

    class << User
      def new_from_omniauth(email)
        ...
      end
    end

    def self.new_from_omniauth(email)
      ...
    end

    def User.new_from_omniauth(email)
      ...
    end
  end

  class << User
    def new_from_omniauth(email)
      ...
    end
  end

  def User.new_from_omniauth(email)
    ...
  end

Where is print defined?


    show-source Object#print

    From: io.c (C Method):
    Owner: Kernel
    Visibility: private
    Number of lines: 6

    static VALUE
    rb_f_print(int argc, VALUE *argv)
    {
        rb_io_print(argc, argv, rb_stdout);
        return Qnil;
    }
    Object.ancestors.include? Kernel
    => true

Back to square one


    print 'Starting our program!'

    class User
      print 'Defining the User class'

      def initialize
        print 'Registering a new user'
      end
    end

User

#<User:0x007f987>

main

Back to square one


    class User
    end

    User.class
    => Class
    User.class.ancestors.include? Object
    => true
    User.class.private_instance_methods.include? :print
    => true

    borko = User.new

    borko.class
    => User
    borko.class.ancestors.include? Object
    => true
    borko.class.private_instance_methods.include? :print
    => true

Anyone seen puts?

By Damir Svrtan

Anyone seen puts?

  • 1,272