Last active
December 17, 2015 06:08
-
-
Save mifix/5562875 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# see http://blog.codegram.com/2011/4/understanding-class-instance-variables-in-ruby | |
# and http://vimeo.com/33481092 (Ruby's Object Model & Eigenclasses) | |
module MyMixin | |
def self.included(base) | |
base.extend ClassMethods | |
end | |
module ClassMethods | |
# the current class (also called definee or klass) determines on | |
# which class 'def' will act on | |
# | |
# definee => MyMixin::ClassMethods | |
# | |
def set(value) | |
# self points to the current object (also called callee), it | |
# determines on which object a method is called | |
# | |
# self => either A or B | |
# | |
@@my_value = value | |
end | |
def get | |
@@my_value | |
end | |
end | |
end | |
class A | |
include MyMixin | |
set 'Test from A' | |
end | |
class B | |
include MyMixin | |
set 'Test from B' | |
end | |
# we have overwritten MyMixin::ClassMethods::@@my_value | |
A.get # => "Test from B" | |
# methods are defined in module | |
A.singleton_methods # => [:set, :get] | |
A.singleton_methods(false) # => [] | |
A.class_variables # => [] | |
MyMixin::ClassMethods.class_variables # => [:@@my_value] | |
## Summary: | |
# | |
# 'set', 'get' methods are defined in: A's singleton class | |
# 'my_value' is defined in: MyMixin::ClassMethods as class var | |
###################### ###################### | |
module YourMixin | |
def self.included(base) | |
# define_singleton_method essentially means the following: | |
# | |
# base.singleton_class.send :define_method, :set do ...; end | |
# | |
# 'define_method' cares only about 'self' not the current class | |
# | |
# We're creating a singleton method without using 'class' or 'self' | |
# which means, we are not forced into a new scope | |
base.define_singleton_method :set do |value| | |
@my_value = value | |
end | |
base.define_singleton_method :get do | |
@my_value | |
end | |
end | |
end | |
class C | |
include YourMixin | |
set 'Test from C' | |
end | |
class D | |
include YourMixin | |
set 'Test from D' | |
end | |
C.get # => "Test from C" | |
# methods are defined in the class' singleton class | |
C.singleton_methods(false) # => [:set, :get] | |
C.class_variables # => [] | |
C.instance_variables # => [:@my_value] | |
## Summary: | |
# | |
# 'set', 'get' methods are defined in: C's singleton class | |
# 'my_value' is defined as C's class instance variable | |
###################### ###################### | |
module HerMixin | |
def self.included(base) | |
base.extend ClassMethods | |
end | |
module ClassMethods | |
def set(value) | |
class_variable_set '@@my_value', value | |
end | |
def get | |
class_variable_get '@@my_value' | |
end | |
end | |
end | |
class E | |
include HerMixin | |
set 'Test from E' | |
end | |
class F | |
include HerMixin | |
set 'Test from F' | |
end | |
E.get # => "Test from E" | |
E.singleton_methods(false) # => [] | |
E.class_variables # => [:@@my_value] | |
## Summary: | |
# | |
# 'set', 'get' methods are defined in: HerMixin module | |
# 'my_value' is defined in: E as class var | |
###################### ###################### | |
module HisMixin | |
def self.included(base) | |
base.extend ClassMethods | |
end | |
module ClassMethods | |
def set(value) | |
@my_value = value | |
end | |
def get | |
@my_value | |
end | |
end | |
end | |
class G | |
include HisMixin | |
set 'Test from G' | |
end | |
class H | |
include HisMixin | |
set 'Test from H' | |
end | |
H.get # => "Test from H" | |
H.singleton_methods(false) # => [] | |
H.class_variables # => [] | |
H.instance_variables # => [:@my_value] | |
## Summary: | |
# | |
# 'set', 'get' methods are defined in: HisMixin module | |
# 'my_value' is defined as H's class instance variable |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment