introduction to the ruby object model

Post on 22-Jan-2018

331 Views

Category:

Software

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Introduction to the

Ruby Object Model

Ruby is an object

oriented language

Primitives

182376

“hello, world”

[1, 2, 3]

Objects

String: “x”

object_id: 2817249

#length, #upcase, #..

Object

@name = “Peter”

@age = 30

object_id: 2132452

Array: [., .]

object_id: 2132452

#next, #size, #..

An Object

#name=(name)

#name

#age=(age)

#age

@name = “Peter”

@age = 30

Data

Methods

class: User

object_id: 2132452

In Ruby: everything (well, almost

everything) is an object:

• Classes

• “Primitive types”

• Modules (will be explained later on)

• Procs

‘a’.upcase # => ‘A’

‘a’.class # => String

10.class # => Fixnum

class Fixnum

def +(other)

42

end

end

10 + 10 # => 42 (!)

Fixnum.class # => Class

Class.class # => Class

my_class = Class.new

my_obj = my_class.new

The “Ruby Object Model”

How Objects Are

Represented Internally

struct RObject {

struct RBasic basic;

long numiv;

VALUE *ivptr;

struct st_table *iv_index_tbl;

};

Number of

instance variables

Instance variables array

Essentially a hash of

{ name -> index into ivptr }

@name = “Fred”

@age = 23

struct RBasic {

VALUE flags;

VALUE klass;

};

Stores information like

whether the object is

frozen, tainted or others

Reference to

whatever the class

of the object is

An object has:

• Klass (parent class)

• Flags (frozen? tainted? etc.)

• Instance variables

• Nothing else.

How Classes Are

Represented Internally

struct RClass {

struct RBasic basic;

rb_classext_t *ptr;

struct st_table *m_tbl;

struct st_table *iv_index_tbl;

};

struct rb_classext_struct {

VALUE super;

struct st_table *iv_tbl;

struct st_table *const_tbl;

};

Instance

variables

Constants

Reference

to superclass

Additional class

info

Methods

Instance

variables

struct RClass {

VALUE flags;

VALUE klass;

VALUE super;

struct st_table *iv_tbl;

struct st_table *const_tbl;

struct st_table *m_tbl;

struct st_table *iv_index_tbl;

};

Methods

Reference

to superclass

Instance

variables

Constants

Instance

variables

class Oban < Scotch

AGE = 14

@tasty = true

def tasty

Oban.instance_variable_get("@tasty")

end

end

class Oban < Scotch

AGE = 14

@tasty = true

def tasty

Oban.instance_variable_get("@tasty")

end

end

basic.klass Class

ptr->super Scotch

iv_tbl { “@tasty” => true }

const_tbl { “AGE” = 14 }

m_tbl { “tasty” => … }

Enough with the C

code!

RObject and RClass

instance variables

flags

RObject

class reference

@age = 10

@name = “Peter”

instance variables

flags

RClass

class reference

methods table

reference to ‘superclass’

constants table

These three are extra to classes

class User

def name=(name)

@name = name

end

def name

@name

end

end

methods table

#name=

#name

class reference

User (RClass)

class instance variables

reference to ‘superclass’

class reference

Class (RClass)

class reference

Object (RClass)

class User

def name=(name)

@name = name

end

def name

@name

end

end

me = User.new

methods table

#name=

#name

User (RClass)class reference

RObject

instance variables

methods table

#name=

#name

User (RClass)class reference

RObject

instance variables

@name => “Peter Cooper”

me.name = “Peter Cooper”

class User

def status

:admin

end

end

methods table

#name=

#name

#status

User (RClass)class reference

RObject

instance variables

@name => “Peter Cooper”

me = User.new

you = User.new

def me.age

30

end

me.age # => ?

you.age # => ?

me = User.new

you = User.new

def me.age

30

end

me.age # => 30

you.age # => NoMethodError

methods table

#name=

#name

User (RClass)

class reference

RObject

Me

class reference

RObject

You

.. but where does

me.age go?

methods table

#name=

#name

User (RClass)

class reference

RObject

Me

class reference

RObject

You

methods table

#age

*me (RClass)

singleton class

class reference

RObject

Me

class reference

RObject

You

*me (RClass)

methods table

#age

superclass

User (RClass)

methods table

#name=

#name

me.class # => User

“Class Methods”

class User

def self.plural_name

“users”

end

end

User.plural_name # => “users”

me.plural_name # => NoMethodError

you.plural_name # => NoMethodError

methods table

#name=

#name

superclass

User (RClass)

klass

Class (RClass)

methods table

#plural_name

*User (RClass)

klass

Object (RClass)

methods table

#name=

#name

superclass

User (RClass)

klass

Class (RClass)

methods table

#plural_name

*User (RClass)

klass

Object (RClass)Conclusion:

All methods in Ruby

are actually

instance methods!

Modules

“Collection of methods

and constants”

module MyModule

PI = 3.141592

def some_method

puts "Hello, world!"

end

end

MyModule::PI # => 3.141592 (yay!)

MyModule.some_method # => NoMethodError (eh!?)

class User

include MyModule

end

me.some_method # => “Hello, world!”

Using modules as “mixins"

class User

include MyModule

end

me.some_method # => “Hello, world!”

“Mixing in” functionality

into an existing class

Using modules as “mixins"

module MyModule

def self.some_method

puts “Hello, world!”

end

end

MyModule.some_method # => “Hello, world!”

Using modules as function grouping in a

namespace (helper/utility classes)

Math.cos(10)

module NamingMethods

def name=(name)

@name = name

end

def name

@name

end

end

class User

include NamingMethods

end

me = User.new

me.name = “Fred”

p me.name

module NamingMethods

def name=(name)

@name = name

end

def name

@name

end

end

class User

include NamingMethods

end

me = User.new

me.name = “Fred”

p me.name

Can anybody guess

what’s going on

behind the scenes?

methods table

#name=

#name

superclass

User (RClass)

methods table

#name=

#name

#hello

NamingMethods (RModule)

Object (RClass)

methods table

#name=

#name

superclass

User (RClass)

methods table

#name=

#name

#hello

NamingMethods (RModule)

Object (RClass)

NamingMethods (IClass)

methods table

superclass

“extend” vs “include”

module ClassMethods

def hello

42

end

end

class User

extend ClassMethods

end

p User.hello # => 42

module SingletonMethods

def hello

42

end

end

str = “hello”

str.extend SingletonMethods

p str.hello # => 42

module MyFunctionality

def instance_meth

puts “I’m an instance method”

end

def self.included(klass)

klass.extend ClassMethods

end

module ClassMethods

def class_meth

puts “I’m a class method”

end

end

end

class MyClass

include MyFunctionality

end

p MyClass.class_meth # => “I’m a class method”

p MyClass.new.instance_meth # => “I’m an instance method”

superclass

MyClass (RClass)methods table

#instance_meth

MyFunctionality (RModule)

Object (RClass)

(IClass)

methods table

superclass

klass

*(IClass)

methods table

superclass

methods table

#class_meth

MyFunctionality::ClassMethods

(RModule)

top related