Small
Ruby Talk










                 http://godfat.org/slide/2013-08-28-small-ruby-talk/

Lisp + Smalltalk

Lisp: Everything is an expression

The followings are expressions:

The followings are expressions:

Valid, but don't do this:


p(if (class C; self; end)
  def f a=(def g a; 'g'; end)
    g a
  end
  g f
end) # => 'g'

Smalltalk: Everything is an object

The followings are objects:

There's more than one
way to do it (perlish)


Object.instance_method(:p).bind(self).call(self)
# => main

Equivalent to:


p self # => main

Today's Topics:

Today's Topics:

Static Typing vs
Dynamic Typing

Extracted from gson


@SuppressWarnings("unchecked")
public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
  if (json == null) {
    return null;
  }
  StringReader reader = new StringReader(json);
  T target = (T) fromJson(reader, typeOfT);
  return target;
}

Duck Typing


Duck.new.walk

Could be thought as:


Object duck = new Duck();
if(duck.isRespondingTo("walk"))
    duck.dispatch("walk");
else
    throw new NoMethodError(duck, "walk");

Today's Topics:

Strong or Weak? Coercion?

Perl Type Coercion


'1' +  1  #   2
 1  . '1' # '11'

JavaScript Type Nonsense


'1' +  1     // '11'
 1  + '1'    // '11'
 true + true //   2
 true + []   // 'true'

More
JavaScript Type Nonsense

ref: GorillaScript

true + null      // 1
true + undefined // NaN
true + {}        // 'true[object Object]'
new Date(0) + 0  // 'Thu Jan 01 1970 08:00:00 GMT+0800 (CST)0'
new Date(0) - 0  // 0

ლ(ಠ益ಠ╬)ლ

Today's Topics:

Object is an Object itself?

Ruby:

Object.kind_of?(Object)   # true
Java:

Object instanceof Object // ?

If A is a kind of B...
B must either be:


#    A's class
     B ==      A.class
# or A's class' superclass
     B ==      A.class.superclass
# or A's class' superclass' superclass
     B ==      A.class.superclass.superclass
# or A's class' superclass' superclass' superclass
     B ==      A.class.superclass.superclass.superclass
# ...

Assume A and B
are both Objects...


#    A's class
     B ==      A.class
# or A's class' superclass
     B ==      A.class.superclass
# or A's class' superclass' superclass
     B ==      A.class.superclass.superclass
# or A's class' superclass' superclass' superclass
     B ==      A.class.superclass.superclass.superclass
# ...

Assume A and B
are both Objects...


# =>      v Class
Object == Object.class
# or A's class' superclass
     B ==      A.class.superclass
# or A's class' superclass' superclass
     B ==      A.class.superclass.superclass
# or A's class' superclass' superclass' superclass
     B ==      A.class.superclass.superclass.superclass
# ...

Assume A and B
are both Objects...


# =>      v Class
Object == Object.class
# =>      v Module
Object == Object.class.superclass
# or A's class' superclass' superclass
     B ==      A.class.superclass.superclass
# or A's class' superclass' superclass' superclass
     B ==      A.class.superclass.superclass.superclass
# ...

Assume A and B
are both Objects...


# =>      v Class
Object == Object.class
# =>      v Module
Object == Object.class.superclass
# =>      v Object
Object == Object.class.superclass.superclass
# or A's class' superclass' superclass' superclass
     B ==      A.class.superclass.superclass.superclass
# ...

Assume A and B
are both Objects...


# =>      v Class
Object == Object.class
# =>      v Module
Object == Object.class.superclass
# =>      v Object
Object == Object.class.superclass.superclass
# =>      v BasicObject
Object == Object.class.superclass.superclass.superclass
# ...

Thus:


Object.new.kind_of?(Object) # true
# because
Object == Object.new.class

Also:


Object    .kind_of?(Object) # true
# because
Object == Object    .class.superclass.superclass

Smalltalk: Everything is an object

Ruby: Even Object is an Object itself

Cool facts:
Class is also a Class itself


 Class.kind_of?(Class ) # => true
# because
 Class.class            # => Class
# thus
 Class ==  Class.class

Cool facts:
Class/Module is also a Class/Module itself


Module.kind_of?(Module) # => true
# because
Module.class            # => Class
# thus
Module == Module.class.superclass

Today's Topics:

Singleton Pattern


require 'singleton'
class Mario
  include Singleton


  def greets
    puts "It's me, Mario!"
  end
end
Mario.instance.greets

Singleton Pattern Underneath


# (simplified)
class Mario
  def self.instance
    @instance ||= new
  end
  def greets
    puts "It's me, Mario!"
  end
end
Mario.instance.greets

Singleton Pattern *Simplest*



Mario = Object.new



  def Mario.greets
    puts "It's me, Mario!"
  end

Mario.greets

Introducing Singleton Class

Also called
Metaclass (Smalltalk) or
Eigenclass


Mario.singleton_class
# => #<Class:#<Object:0xDEADBEEF>>

Introducing Singleton Class

Also called
Metaclass (Smalltalk) or
Eigenclass

An instance's method is defined in its
singleton_class

If and only if

The other instances of the same class do not have the same method

forget about some hacks for now

Mario is an Object



Mario = Object.new



  def Mario.greets
    puts "It's me, Mario!"
  end

Mario.greets

The other Objects do not greet


# ...like a Mario!







# NoMethodError: undefined method `greets'
Object.new.greets

So class methods are
singleton methods!

Remember?

An instance's method is defined in its
singleton_class

If and only if

The other instances of the same class do not have the same method

Time is an instance of Class,
But the other Classes
Do not have this method:

Time.at(0)

The other instances of the same class do not have the same method

So class methods are
singleton methods!


Time.class # => Class
Time.at(0) # => 1970-01-01 08:00:00 +0800
Hash.class # => Class
Hash.at(0) # => NoMethodError: undefined method

Time.at is defined in Time's singleton class.
The same as Mario.greet

So class methods are
singleton methods!


  def Mario.greet; puts "It's me, Mario!"; end
Mario.singleton_class.module_eval do
  def       greet; puts "It's me, Mario!"; end
end

Time.at is defined in Time's singleton class.
The same as Mario.greet

Don't get confused.

Ruby's singleton class

Has nothing to do with

Singleton pattern.

...It's eigenclass after all

If

We need to go deeper

For Method Dispatching

Checkout my other slides for: Rubinius on 2008-12-21

Today's Topics:

A taste of Muack


require 'muack'
include Muack::API
Mario = 'Mario'
mock(Mario).greet{ "It's me, #{Mario.reverse}!" }
mock(Mario).reverse.proxy.returns(&:reverse)
puts Mario.greet # "It's me, Mario!"
Muack.verify

any_instance_of


Luigi = Class.new{
           def greet; "It's me, #{self}!" end }
any_instance_of(Luigi) do |luigi|
  mock(luigi).to_s.proxy.returns{ |s| s[/\w+/] }
end
puts Luigi.new.greet # It's me, Luigi!
Muack.verify

Trick in AnyInstanceOf:


Muack::AnyInstanceOf =
  Class.new(Struct.new(:singleton_class))

Fake singleton class as class


Muack::AnyInstanceOf.new(Luigi).
  singleton_class == Luigi # true

If

We need to go deeper

For Muack

Use the Source, Tux!

Q?