Goal: to grok this codeclass Post < ActiveRecord::Base <= class extension mixin belongs_to :user               <= macroend...
Coming from a compiledlanguage, runtime execution is  foreign, all code is executed               code    Post.respond_to?...
Classes are also like namespaces               too.class MyClass puts ‘Hello World’end# => Hello World
Eigenclasses
Singleton method variations on     the MyClass instance  class MyClass   def MyClass.my_method; end   def self.my_method; ...
class << Object puts self def my_method                     Different  puts ‘hi’ endendclass Object           class << Obj...
Including the module in the Eigenclass of     class C to create class methods   module M    def my_method     puts ‘hi’   ...
Using extend to add class methods to C      module M       def my_method         puts ‘hi’       end      end      class C...
Class methods are singletons of          the class object, that means they                 are in the eigenclassclass C   ...
Examining self…class Foo           Self, the current object, is changed puts self          by opening up the eigenclass an...
Hook methods or   callbacks
HookingModule#included exists solelyas a callback and the defaultimplementation is empty.
Hook methods - Module#included  module Mod1   class << self    def included(othermod)      puts "Mod1 was mixed into #{oth...
Hook methods - Module#include(must call super if you override, to actually include                     the module)    modu...
Putting stuff together…
module Associations                     This is obviously very dumbed down, but                                         no...
module ActiveRecord module Associations  def self.included(base)   base.extend(ClassMethods)  end  module ClassMethods   d...
Ghost Methodsclass Post                                  #method_missing def initialize                             catche...
Upcoming SlideShare
Loading in …5
×

Lightning talk

308 views
252 views

Published on

metaprogramming

Published in: Spiritual
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
308
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Lightning talk

  1. 1. Goal: to grok this codeclass Post < ActiveRecord::Base <= class extension mixin belongs_to :user <= macroendmy_post = Post.newmy_post.name = Chile L‘ <= employs #method_missingmy_post.subject = traveling in thailandmy_post.content = sometimes you can almost not tell thedifferencemy_post.save!
  2. 2. Coming from a compiledlanguage, runtime execution is foreign, all code is executed code Post.respond_to? Name Ruby is a dynamic language
  3. 3. Classes are also like namespaces too.class MyClass puts ‘Hello World’end# => Hello World
  4. 4. Eigenclasses
  5. 5. Singleton method variations on the MyClass instance class MyClass def MyClass.my_method; end def self.my_method; end class << self def my_method; end end end
  6. 6. class << Object puts self def my_method Different puts ‘hi’ endendclass Object class << Object is adding methods to the eigenclass of Object. This method is now available to all objects as if it were a class def self.meth2 puts self method. puts ‘there’ end However, opening the Object class and adding methods to self class << self shows the current object is the instance Foo. def meth3 puts self puts ‘hahaha’ end endendFoo = Class.newFoo.my_methodFoo.meth2Foo.meth3# => #<Class:Object># => hi# => Foo# => there# => Foo# => hahaha
  7. 7. Including the module in the Eigenclass of class C to create class methods module M def my_method puts ‘hi’ end end class C class << self include M end end C.my_method # => hi
  8. 8. Using extend to add class methods to C module M def my_method puts ‘hi’ end end class C extend M end C.my_method # => hi
  9. 9. Class methods are singletons of the class object, that means they are in the eigenclassclass C Self, therefore the current object, is puts self changed by opening up the class << self eigenclass puts self def my_method puts ‘hi’ end endendC.my_method # => C # => #<Class:C> # => hi
  10. 10. Examining self…class Foo Self, the current object, is changed puts self by opening up the eigenclass and class << self we are now adding my_method to puts self the Foo instance, but this is def my_method equivalent to Foo.my_method puts ‘hi’ end endendFoo.my_method # => Foo # => #<Class:Foo> # => hi
  11. 11. Hook methods or callbacks
  12. 12. HookingModule#included exists solelyas a callback and the defaultimplementation is empty.
  13. 13. Hook methods - Module#included module Mod1 class << self def included(othermod) puts "Mod1 was mixed into #{othermod}" end end end class MyClass include Mod1 end # => Mod1 was mixed into MyClass
  14. 14. Hook methods - Module#include(must call super if you override, to actually include the module) module Mod1; end module Mod2; end class MyClass def self.include(*modules) puts “#{modules} included” super end include Mod1 include Mod2 end # => [Mod1] included # => [Mod2] included
  15. 15. Putting stuff together…
  16. 16. module Associations This is obviously very dumbed down, but now we can start to see some things in def self.included(base) action. base.extend(ClassMethods) end We have defined the module Associations which includes a submodule module ClassMethods ClassMethods which will hold class def belongs_to methods. “I am in the ClassMethods module” end Overriding included now acts on the end including class which is base in this case. end This class is sometimes called the inclusor. The extend method adds the class Base ClassMethods to the inclusor’s include Associations eigenclass. end Now the Base class can include theclass Post < Base Associations module and our model can belongs_to inherit from Baseend One more step…
  17. 17. module ActiveRecord module Associations def self.included(base) base.extend(ClassMethods) end module ClassMethods def belongs_to “I am in the ClassMethods module” end end end class Base include Associations endendclass Post < ActiveRecord::Base belongs_toendAdd an ActiveRecord Namespace and we have somethingresembling the original
  18. 18. Ghost Methodsclass Post #method_missing def initialize catches the call to @attributes = {} name=() or returns end def method_missing(name, *args) the value when it attribute = name.to_s gets a method if attribute =~ /=$/ without an ‘=‘ @attributes[attribute.chop] = args[0] else It chops off the @attributes[attribute] equals sign to get end end the attribute nameend and then sets themy_post = Post.new hash valuemy_post.name = ‘Chile L’

×