ruby conf india 2016
TRANSCRIPT
Ruby is Awesome!
–Sumit Mahamuni@meetmahamuni
https://github.com/sumitmah
Some Background about the talk
class Foo def public_method puts "I'm Public" end
protected def protected_method puts "I'm protected" end
private def private_method puts "I'm private" endend
> foo = Foo.new> foo.public_method #=> I'm Public
> foo.protected_method > NoMethodError: protected method `protected_method' called for #<Foo>
> foo.private_method #=>NoMethodError: private method `private_method' called for #<Foo>
class Bar < Fooend
> bar = Bar.new> bar.public_method #=> I'm Public
> bar.protected_method #=> NoMethodError: protected method `protected_method' called for #<Foo>
> bar.private_method #=>NoMethodError: private method `private_method' called for #<Foo>
class Foo private def private_method puts "I'm private" end
def self.private_method puts "I'm private" endend
> foo = Foo.new> foo.private_method #=> NoMethodError: private method `private_method' called for #<Foo>
> Foo.private_method #=> I'm private
foom_table
Foo
instance_private_method
#<Class:Foo> m_table
class_private_methodclass Foo private def instance_private_method puts "I'm private" end
def self.class_private_method puts "I'm private" endend
What is “private”?
/* vm_method.c */voidInit_eval_method(void){ ... rb_define_private_method(rb_cModule, “private", rb_mod_private, -1); ...}
/* class.c */
static VALUEboot_defclass(const char *name, VALUE super);
voidInit_class_hierarchy(void){ rb_cBasicObject = boot_defclass("BasicObject", 0); rb_cObject = boot_defclass("Object", rb_cBasicObject); rb_cModule = boot_defclass("Module", rb_cObject); rb_cClass = boot_defclass("Class", rb_cModule); …}
Object structure
> class A> end => nil
> A.class => Class
> A.class.ancestors => [Class, Module, Object, Kernel, BasicObject]
class WhatIsPrivate privateend
/* vm_method.c */static voidvm_cref_set_visibility(rb_method_visibility_t method_visi, int module_func){ rb_scope_visibility_t *scope_visi = (rb_scope_visibility_t*)&rb_vm_cref()->scope_visi;
scope_visi->method_visi = method_visi; scope_visi->module_func = module_func;}
/* vm.c */rb_cref_t *rb_vm_cref(void){ rb_thread_t *th = GET_THREAD(); rb_control_frame_t *cfp =
rb_vm_get_ruby_level_next_cfp(th, th->cfp);
if (cfp == NULL) { return NULL; } return rb_vm_get_cref(cfp->ep);}
This image is taken from Ruby under microscope book.
This image is taken from Ruby under microscope book.
class WhatIsDefineMethod private def i_am_private end def self.method_defined_on_self_objectendend
static voidvm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval, int is_singleton);
/* vm.c */
static voidvm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval, int is_singleton){ VALUE klass; rb_method_visibility_t visi; rb_cref_t *cref = rb_vm_cref();
if (!is_singleton) { klass = CREF_CLASS(cref); visi = rb_scope_visibility_get(); } else { /* singleton */
/* class and frozen checked in this API */ klass = rb_singleton_class(obj); visi = METHOD_VISI_PUBLIC; } …}
static rb_method_visibility_trb_scope_visibility_get(void){ rb_thread_t *th = GET_THREAD(); rb_control_frame_t *cfp =
rb_vm_get_ruby_level_next_cfp(th, th->cfp);
if (!vm_env_cref_by_cref(cfp->ep)) { return METHOD_VISI_PUBLIC; } else { return
CREF_SCOPE_VISI(rb_vm_cref())->method_visi; }}
object
class WhatIsDefineMethod private def i_am_private end def self.method_defined_on_self_object endend
m_table
WhatIsDefineMethod
i_am_private
#<Class:WhatIsDefineMethod>
m_table
method_defined_on_self_object
class AnyClass class << self def any_public_method end
protected def any_protected_method end
private def any_private_method end endend
CFP[AnyClass]
CFP
CFP
CFP[self]
Ruby call stack
–Sumit Mahamuni@meetmahamuni
https://github.com/sumitmah
“Thanks.”