Ruby object model - Understanding of object play role for ruby
Introduction to the Ruby Object Model
-
Upload
miki-shiran -
Category
Software
-
view
331 -
download
1
Transcript of Introduction to the Ruby Object Model
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)