SlideShare une entreprise Scribd logo
1  sur  108
MODULE MAGIC
 and my trip to RubyKaigi2009
JAMES EDWARD
GRAY II
JAMES EDWARD
GRAY II
Created the Ruby Quiz and wrote that book
JAMES EDWARD
GRAY II
Created the Ruby Quiz and wrote that book

Built FasterCSV (now CSV), HighLine (with Greg), Elif, and
some other scarier experiments
JAMES EDWARD
GRAY II
Created the Ruby Quiz and wrote that book

Built FasterCSV (now CSV), HighLine (with Greg), Elif, and
some other scarier experiments

Documented some of Ruby
JAMES EDWARD
GRAY II
Created the Ruby Quiz and wrote that book

Built FasterCSV (now CSV), HighLine (with Greg), Elif, and
some other scarier experiments

Documented some of Ruby

  http://blog.grayproductions.net/
JAMES EDWARD
GRAY II
Created the Ruby Quiz and wrote that book

Built FasterCSV (now CSV), HighLine (with Greg), Elif, and
some other scarier experiments

Documented some of Ruby

  http://blog.grayproductions.net/

  http://twitter.com/JEG2
LSRC SPEECHES
 TV shows geeks should know!
LSRC SPEECHES
 TV shows geeks should know!
RUBYKAIGI2009
RUBYKAIGI2009
RUBYKAIGI2009

See how the Japanese do
conferences
RUBYKAIGI2009

See how the Japanese do
conferences

  The translation time
  allows you to think more
RUBYKAIGI2009

See how the Japanese do
conferences

  The translation time
  allows you to think more

Meet nice Rubyists from
Japan and other places
RUBYKAIGI2009

See how the Japanese do
conferences

  The translation time
  allows you to think more

Meet nice Rubyists from
Japan and other places

See Japan!
MIXIN MODULES
A TRIVIAL MIXIN
 I’m sure most of us know this
module Mixin
  def shared_method
    puts "Called!"
  end
end

class Whatever
  include Mixin
end

Whatever.new.shared_method




   A TRIVIAL MIXIN
        I’m sure most of us know this
module Mixin
  def shared_method
    puts "Called!"
  end
end

class Whatever
                              Called!
  include Mixin
end

Whatever.new.shared_method




   A TRIVIAL MIXIN
        I’m sure most of us know this
class A
  def call
    puts "A"
  end
end

%w[B C D].each do |name|
  eval <<-END_RUBY
  module #{name}
    def call
      puts "#{name}"
      super
    end
  end
  END_RUBY
end

class E < A
  include B
  include C
  include D
  def call
    puts "E"
    super
  end
end

E.new.call
E
class A
  def call
    puts "A"
  end
end




                           D
%w[B C D].each do |name|
  eval <<-END_RUBY
  module #{name}
    def call
      puts "#{name}"
      super



                           C
    end
  end
  END_RUBY
end




                           B
class E < A
  include B
  include C
  include D
  def call
    puts "E"



                           A
    super
  end
end

E.new.call
INHERITANCE
   p E.ancestors
[E, D, C, B, A, Object, Kernel, BasicObject]




       INHERITANCE
                p E.ancestors
class A
  def call
    puts "A"
  end
end

%w[B C D].each do |name|
  eval <<-END_RUBY
  module #{name}
    def call
      puts "#{name}"
      super
    end
  end
  END_RUBY
end

a = A.new
a.extend(B)
a.extend(C)
a.extend(D)
a.call
D
class A
  def call
    puts "A"
  end
end




                           C
%w[B C D].each do |name|
  eval <<-END_RUBY
  module #{name}
    def call
      puts "#{name}"
      super



                           B
    end
  end
  END_RUBY
end




                           A
a = A.new
a.extend(B)
a.extend(C)
a.extend(D)
a.call
INVISIBLE CLASS
  class << a; p ancestors end
[D, C, B, A, Object, Kernel, BasicObject]




    INVISIBLE CLASS
          class << a; p ancestors end
The (invisible) “singleton class” is here


[D, C, B, A, Object, Kernel, BasicObject]




    INVISIBLE CLASS
           class << a; p ancestors end
class A
  def call
    puts "A"
  end
end

%w[B C D].each do |name|
  eval <<-END_RUBY
  module #{name}
    def call
      puts "#{name}"
      super
    end
  end
  END_RUBY
end

a = A.new
a.extend(B)
a.extend(C)
a.extend(D)
class << a
  def call
    puts "Invisible"
    super
  end
end
a.call
class A
  def call
    puts "A"
  end


                           Invisible
end

%w[B C D].each do |name|
  eval <<-END_RUBY


                               D
  module #{name}
    def call
      puts "#{name}"
      super


                               C
    end
  end
  END_RUBY
end



                               B
a = A.new
a.extend(B)
a.extend(C)
a.extend(D)


                               A
class << a
  def call
    puts "Invisible"
    super
  end
end
a.call
JUST A SHORTCUT
We now know what extend() rea#y is
obj.extend(Mod)




   JUST A SHORTCUT
     We now know what extend() rea#y is
class << obj
obj.extend(Mod)     include Mod
                  end


   JUST A SHORTCUT
     We now know what extend() rea#y is
NAMESPACE
 MODULES
GROUP CONSTANTS
Group constants/classes and even mix them in
class Logger
  # ...
  # Logging severity.
  module Severity
    DEBUG    = 0
    INFO     = 1
    WARN     = 2
    ERROR    = 3
    FATAL    = 4
    UNKNOWN = 5
  end
  include Severity
  # ...
end




  GROUP CONSTANTS
  Group constants/classes and even mix them in
class Logger            module JSON
  # ...
  # Logging severity.     class Array
  module Severity
    DEBUG    = 0
                            # ...
    INFO     = 1          end
    WARN     = 2
    ERROR    = 3          class Object
    FATAL    = 4
    UNKNOWN = 5
                            # ...
  end                     end
  include Severity
  # ...                   # ...
end                     end



  GROUP CONSTANTS
  Group constants/classes and even mix them in
DUAL INTERFACE
Some modules are both a namespace and a mixin
module MoreMath
  def self.dist(x1, y1, x2, y2)
    Math.sqrt( (x2 - x1) ** 2 +
               (y2 - y1) ** 2 )
  end
end




    DUAL INTERFACE
Some modules are both a namespace and a mixin
module MoreMath                   module MoreMath
  def self.dist(x1, y1, x2, y2)     extend Math
                                    def self.dist( x1, y1,
    Math.sqrt( (x2 - x1) ** 2 +                    x2, y2 )
               (y2 - y1) ** 2 )       sqrt( (x2 - x1) ** 2 +
                                            (y2 - y1) ** 2 )
  end                               end
                                  end
end




    DUAL INTERFACE
Some modules are both a namespace and a mixin
MIXIN YOURSELF
Better than Ruby’s module_function()
module MiniLogger
  extend self
  def logger
    $stdout
  end
  def log(message)
    logger.puts "%s: %s" %
                [ Time.now.strftime("%D %H:%M:%S"),
                  message ]
  end
end

if __FILE__ == $PROGRAM_NAME
  MiniLogger.log "Called as a module method and " +
                 "written to $stdout."
end




       MIXIN YOURSELF
          Better than Ruby’s module_function()
module MiniLogger                                     require "mini_logger"
  extend self
  def logger                                          class Whatever
    $stdout                                             include MiniLogger
  end                                                   def logger
  def log(message)                                        @logger ||=
                                                          open("whatever.log", "w")
    logger.puts "%s: %s" %
                                                        end
                [ Time.now.strftime("%D %H:%M:%S"),
                                                        def initialize
                  message ]
                                                          log "Called as an "    +
  end                                                         "instance method " +
end                                                           "and written to " +
                                                              "a file."
if __FILE__ == $PROGRAM_NAME                            end
  MiniLogger.log "Called as a module method and " +   end
                 "written to $stdout."
end                                                   Whatever.new




       MIXIN YOURSELF
          Better than Ruby’s module_function()
LIMITED MAGIC
Summon new error types as needed
module Errors
  class BaseError < RuntimeError; end

  def self.const_missing(error_name)
    if error_name.to_s =~ /wErrorz/
      const_set(error_name, Class.new(BaseError))
    else
      super
    end
  end
end

p Errors::SaveError




    LIMITED MAGIC
     Summon new error types as needed
SOME EXAMPLES
Bridging the theory to implementation gap
SOME EXAMPLES
Bridging the theory to implementation gap
A BIT TOO CLEVER
If RDoc can’t read it, it’s probably too clever
require "ostruct"

class << Config = OpenStruct.new
  def update_from_config_file(path = config_file)
    eval <<-END_UPDATE
    config = self
    #{File.read(path)}
    config
    END_UPDATE
  end
  # ...
end

Config.config_file = "config.rb"
Config.update_from_config_file




     A BIT TOO CLEVER
    If RDoc can’t read it, it’s probably too clever
require "ostruct"

class << Config = OpenStruct.new
  def update_from_config_file(path = config_file)
    eval <<-END_UPDATE
    config = self
    #{File.read(path)}                              config.command = "ls"
    config                                          config.retries = 42
    END_UPDATE                                      # ...
  end
  # ...
end

Config.config_file = "config.rb"
Config.update_from_config_file




     A BIT TOO CLEVER
    If RDoc can’t read it, it’s probably too clever
LESS MAGIC
RDoc and I can both read it now
require "ostruct"

# These extra methods are mixed into the OpenStruct stored in Config.
module Configured
  # This method loads configuration settings from a plain Ruby file.
  def update_from_config_file(path = config_file)
    eval <<-END_UPDATE
    config = self
    #{File.read(path)}
    config
    END_UPDATE
  end
  # ...
end
# This constant holds all global configuration, see Configured for details.
Config = OpenStruct.new.extend(Configured)




               LESS MAGIC
           RDoc and I can both read it now
WITH CLASS METHODS
  A classic pattern made popular by Rails
module DoubleMixin
    module ClassMethods
      # ...
    end
    module InstanceMethods
      # ...
    end

    def self.included(receiver)
      receiver.extend(ClassMethods)
      receiver.send(:include, InstanceMethods)
    end
  end




WITH CLASS METHODS
  A classic pattern made popular by Rails
LABELING OBJECTS
You can use a do-nothing module as a type
module DRb
   # ...
   module DRbUndumped
     def _dump(dummy) # :nodoc:
       raise TypeError, 'can't dump'
     end
   end
   # ...
   class DRbMessage
     # ...
     def dump(obj, error=false) # :nodoc:
       obj = make_proxy(obj, error) if obj.kind_of? DRbUndumped
       # ...
     end
     # ...
   end
   # ...
 end




LABELING OBJECTS
You can use a do-nothing module as a type
OBJECT EDITING
  Using hooks to edit objects
p "ruby".strip!.
         capitalize!

# NoMethodError:
#   undefined method
#   `capitalize!' for
#   nil:NilClass




      OBJECT EDITING
               Using hooks to edit objects
module SafelyChainable
                          def self.extended(singleton)
                            singleton.methods.grep(/w!z/).
                                      each do |bang|
p "ruby".strip!.              singleton.instance_eval <<-END_RUBY
                              def #{bang}
         capitalize!
                                super
                                self
# NoMethodError:
                              end
#   undefined method          END_RUBY
#   `capitalize!' for       end
#   nil:NilClass          end
                        end

                        p "ruby".extend(SafelyChainable).
                                 strip!.capitalize!




      OBJECT EDITING
               Using hooks to edit objects
SUMMARY
SUMMARY
SUMMARY

Master Ruby’s method
lookup; it’s worth the effort
SUMMARY

Master Ruby’s method
lookup; it’s worth the effort

Modules are a terrific at
limiting the scope of magic
SUMMARY

Master Ruby’s method
lookup; it’s worth the effort

Modules are a terrific at
limiting the scope of magic

Remember, modules can
modify individual objects
SUMMARY

Master Ruby’s method
lookup; it’s worth the effort

Modules are a terrific at
limiting the scope of magic

Remember, modules can
modify individual objects

  Try replacing some
  inheritance with extend()
QUESTIONS?

Contenu connexe

Tendances (20)

Groovy intro for OUDL
Groovy intro for OUDLGroovy intro for OUDL
Groovy intro for OUDL
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5
 
Web 4 | Core JavaScript
Web 4 | Core JavaScriptWeb 4 | Core JavaScript
Web 4 | Core JavaScript
 
block
blockblock
block
 
Polyglot JVM
Polyglot JVMPolyglot JVM
Polyglot JVM
 
Clean code
Clean codeClean code
Clean code
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5
 
PHP PPT FILE
PHP PPT FILEPHP PPT FILE
PHP PPT FILE
 
Things about Functional JavaScript
Things about Functional JavaScriptThings about Functional JavaScript
Things about Functional JavaScript
 
Web 9 | OOP in PHP
Web 9 | OOP in PHPWeb 9 | OOP in PHP
Web 9 | OOP in PHP
 
35 Years of Open Source Software
35 Years of Open Source Software35 Years of Open Source Software
35 Years of Open Source Software
 
Functions in PHP
Functions in PHPFunctions in PHP
Functions in PHP
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
 
Objective-c Runtime
Objective-c RuntimeObjective-c Runtime
Objective-c Runtime
 
PHP Traits
PHP TraitsPHP Traits
PHP Traits
 
Web 8 | Introduction to PHP
Web 8 | Introduction to PHPWeb 8 | Introduction to PHP
Web 8 | Introduction to PHP
 
Python advance
Python advancePython advance
Python advance
 
Steady with ruby
Steady with rubySteady with ruby
Steady with ruby
 
Twig tips and tricks
Twig tips and tricksTwig tips and tricks
Twig tips and tricks
 
Web 11 | AJAX + JSON + PHP
Web 11 | AJAX + JSON + PHPWeb 11 | AJAX + JSON + PHP
Web 11 | AJAX + JSON + PHP
 

Similaire à Module Magic

JRuby e DSL
JRuby e DSLJRuby e DSL
JRuby e DSLjodosha
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101Nando Vieira
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v RubyJano Suchal
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Pedro Cunha
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosEdgar Suarez
 
Reusable Ruby • Rt 9 Ruby Group • Jun 2012
Reusable Ruby • Rt 9 Ruby Group • Jun 2012Reusable Ruby • Rt 9 Ruby Group • Jun 2012
Reusable Ruby • Rt 9 Ruby Group • Jun 2012skinandbones
 
Have Your Cake and Eat It Too: Meta-Programming Techniques for Java
Have Your Cake and Eat It Too: Meta-Programming Techniques for JavaHave Your Cake and Eat It Too: Meta-Programming Techniques for Java
Have Your Cake and Eat It Too: Meta-Programming Techniques for JavaHoward Lewis Ship
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Coxlachie
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Metaprogramming Rails
Metaprogramming RailsMetaprogramming Rails
Metaprogramming RailsJustus Eapen
 
Rails3ハンズオン資料
Rails3ハンズオン資料Rails3ハンズオン資料
Rails3ハンズオン資料Shinsaku Chikura
 
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012Rajmahendra Hegde
 

Similaire à Module Magic (20)

Designing Ruby APIs
Designing Ruby APIsDesigning Ruby APIs
Designing Ruby APIs
 
Dsl
DslDsl
Dsl
 
JRuby e DSL
JRuby e DSLJRuby e DSL
JRuby e DSL
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Ruby tricks2
Ruby tricks2Ruby tricks2
Ruby tricks2
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11
 
Why ruby
Why rubyWhy ruby
Why ruby
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
Reusable Ruby • Rt 9 Ruby Group • Jun 2012
Reusable Ruby • Rt 9 Ruby Group • Jun 2012Reusable Ruby • Rt 9 Ruby Group • Jun 2012
Reusable Ruby • Rt 9 Ruby Group • Jun 2012
 
Groovy to gradle
Groovy to gradleGroovy to gradle
Groovy to gradle
 
Have Your Cake and Eat It Too: Meta-Programming Techniques for Java
Have Your Cake and Eat It Too: Meta-Programming Techniques for JavaHave Your Cake and Eat It Too: Meta-Programming Techniques for Java
Have Your Cake and Eat It Too: Meta-Programming Techniques for Java
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Metaprogramming Rails
Metaprogramming RailsMetaprogramming Rails
Metaprogramming Rails
 
Rails3ハンズオン資料
Rails3ハンズオン資料Rails3ハンズオン資料
Rails3ハンズオン資料
 
Ruby
RubyRuby
Ruby
 
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
 

Plus de James Gray

A Dickens of A Keynote
A Dickens of A KeynoteA Dickens of A Keynote
A Dickens of A KeynoteJames Gray
 
Regular expressions
Regular expressionsRegular expressions
Regular expressionsJames Gray
 
Counting on God
Counting on GodCounting on God
Counting on GodJames Gray
 
In the Back of Your Mind
In the Back of Your MindIn the Back of Your Mind
In the Back of Your MindJames Gray
 
Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)James Gray
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHubJames Gray
 
Test Coverage in Rails
Test Coverage in RailsTest Coverage in Rails
Test Coverage in RailsJames Gray
 
Rails Routing And Rendering
Rails Routing And RenderingRails Routing And Rendering
Rails Routing And RenderingJames Gray
 
Sending Email with Rails
Sending Email with RailsSending Email with Rails
Sending Email with RailsJames Gray
 
Associations in Rails
Associations in RailsAssociations in Rails
Associations in RailsJames Gray
 
DRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersDRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersJames Gray
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails InterfaceJames Gray
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model BasicsJames Gray
 
Wed Development on Rails
Wed Development on RailsWed Development on Rails
Wed Development on RailsJames Gray
 

Plus de James Gray (18)

A Dickens of A Keynote
A Dickens of A KeynoteA Dickens of A Keynote
A Dickens of A Keynote
 
I Doubt That!
I Doubt That!I Doubt That!
I Doubt That!
 
Regular expressions
Regular expressionsRegular expressions
Regular expressions
 
Counting on God
Counting on GodCounting on God
Counting on God
 
In the Back of Your Mind
In the Back of Your MindIn the Back of Your Mind
In the Back of Your Mind
 
Unblocked
UnblockedUnblocked
Unblocked
 
API Design
API DesignAPI Design
API Design
 
Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHub
 
Test Coverage in Rails
Test Coverage in RailsTest Coverage in Rails
Test Coverage in Rails
 
Rails Routing And Rendering
Rails Routing And RenderingRails Routing And Rendering
Rails Routing And Rendering
 
Sending Email with Rails
Sending Email with RailsSending Email with Rails
Sending Email with Rails
 
Associations in Rails
Associations in RailsAssociations in Rails
Associations in Rails
 
DRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersDRYing Up Rails Views and Controllers
DRYing Up Rails Views and Controllers
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails Interface
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model Basics
 
Ruby
RubyRuby
Ruby
 
Wed Development on Rails
Wed Development on RailsWed Development on Rails
Wed Development on Rails
 

Dernier

React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 

Dernier (20)

React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 

Module Magic

  • 1. MODULE MAGIC and my trip to RubyKaigi2009
  • 3. JAMES EDWARD GRAY II Created the Ruby Quiz and wrote that book
  • 4. JAMES EDWARD GRAY II Created the Ruby Quiz and wrote that book Built FasterCSV (now CSV), HighLine (with Greg), Elif, and some other scarier experiments
  • 5. JAMES EDWARD GRAY II Created the Ruby Quiz and wrote that book Built FasterCSV (now CSV), HighLine (with Greg), Elif, and some other scarier experiments Documented some of Ruby
  • 6. JAMES EDWARD GRAY II Created the Ruby Quiz and wrote that book Built FasterCSV (now CSV), HighLine (with Greg), Elif, and some other scarier experiments Documented some of Ruby http://blog.grayproductions.net/
  • 7. JAMES EDWARD GRAY II Created the Ruby Quiz and wrote that book Built FasterCSV (now CSV), HighLine (with Greg), Elif, and some other scarier experiments Documented some of Ruby http://blog.grayproductions.net/ http://twitter.com/JEG2
  • 8. LSRC SPEECHES TV shows geeks should know!
  • 9. LSRC SPEECHES TV shows geeks should know!
  • 12. RUBYKAIGI2009 See how the Japanese do conferences
  • 13. RUBYKAIGI2009 See how the Japanese do conferences The translation time allows you to think more
  • 14. RUBYKAIGI2009 See how the Japanese do conferences The translation time allows you to think more Meet nice Rubyists from Japan and other places
  • 15. RUBYKAIGI2009 See how the Japanese do conferences The translation time allows you to think more Meet nice Rubyists from Japan and other places See Japan!
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 30. A TRIVIAL MIXIN I’m sure most of us know this
  • 31. module Mixin def shared_method puts "Called!" end end class Whatever include Mixin end Whatever.new.shared_method A TRIVIAL MIXIN I’m sure most of us know this
  • 32. module Mixin def shared_method puts "Called!" end end class Whatever Called! include Mixin end Whatever.new.shared_method A TRIVIAL MIXIN I’m sure most of us know this
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38. class A def call puts "A" end end %w[B C D].each do |name| eval <<-END_RUBY module #{name} def call puts "#{name}" super end end END_RUBY end class E < A include B include C include D def call puts "E" super end end E.new.call
  • 39. E class A def call puts "A" end end D %w[B C D].each do |name| eval <<-END_RUBY module #{name} def call puts "#{name}" super C end end END_RUBY end B class E < A include B include C include D def call puts "E" A super end end E.new.call
  • 40. INHERITANCE p E.ancestors
  • 41. [E, D, C, B, A, Object, Kernel, BasicObject] INHERITANCE p E.ancestors
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47. class A def call puts "A" end end %w[B C D].each do |name| eval <<-END_RUBY module #{name} def call puts "#{name}" super end end END_RUBY end a = A.new a.extend(B) a.extend(C) a.extend(D) a.call
  • 48. D class A def call puts "A" end end C %w[B C D].each do |name| eval <<-END_RUBY module #{name} def call puts "#{name}" super B end end END_RUBY end A a = A.new a.extend(B) a.extend(C) a.extend(D) a.call
  • 49. INVISIBLE CLASS class << a; p ancestors end
  • 50. [D, C, B, A, Object, Kernel, BasicObject] INVISIBLE CLASS class << a; p ancestors end
  • 51. The (invisible) “singleton class” is here [D, C, B, A, Object, Kernel, BasicObject] INVISIBLE CLASS class << a; p ancestors end
  • 52.
  • 53. class A def call puts "A" end end %w[B C D].each do |name| eval <<-END_RUBY module #{name} def call puts "#{name}" super end end END_RUBY end a = A.new a.extend(B) a.extend(C) a.extend(D) class << a def call puts "Invisible" super end end a.call
  • 54. class A def call puts "A" end Invisible end %w[B C D].each do |name| eval <<-END_RUBY D module #{name} def call puts "#{name}" super C end end END_RUBY end B a = A.new a.extend(B) a.extend(C) a.extend(D) A class << a def call puts "Invisible" super end end a.call
  • 55. JUST A SHORTCUT We now know what extend() rea#y is
  • 56. obj.extend(Mod) JUST A SHORTCUT We now know what extend() rea#y is
  • 57. class << obj obj.extend(Mod) include Mod end JUST A SHORTCUT We now know what extend() rea#y is
  • 58.
  • 61. class Logger # ... # Logging severity. module Severity DEBUG = 0 INFO = 1 WARN = 2 ERROR = 3 FATAL = 4 UNKNOWN = 5 end include Severity # ... end GROUP CONSTANTS Group constants/classes and even mix them in
  • 62. class Logger module JSON # ... # Logging severity. class Array module Severity DEBUG = 0 # ... INFO = 1 end WARN = 2 ERROR = 3 class Object FATAL = 4 UNKNOWN = 5 # ... end end include Severity # ... # ... end end GROUP CONSTANTS Group constants/classes and even mix them in
  • 63.
  • 64.
  • 65.
  • 66.
  • 67. DUAL INTERFACE Some modules are both a namespace and a mixin
  • 68. module MoreMath def self.dist(x1, y1, x2, y2) Math.sqrt( (x2 - x1) ** 2 + (y2 - y1) ** 2 ) end end DUAL INTERFACE Some modules are both a namespace and a mixin
  • 69. module MoreMath module MoreMath def self.dist(x1, y1, x2, y2) extend Math def self.dist( x1, y1, Math.sqrt( (x2 - x1) ** 2 + x2, y2 ) (y2 - y1) ** 2 ) sqrt( (x2 - x1) ** 2 + (y2 - y1) ** 2 ) end end end end DUAL INTERFACE Some modules are both a namespace and a mixin
  • 70. MIXIN YOURSELF Better than Ruby’s module_function()
  • 71. module MiniLogger extend self def logger $stdout end def log(message) logger.puts "%s: %s" % [ Time.now.strftime("%D %H:%M:%S"), message ] end end if __FILE__ == $PROGRAM_NAME MiniLogger.log "Called as a module method and " + "written to $stdout." end MIXIN YOURSELF Better than Ruby’s module_function()
  • 72. module MiniLogger require "mini_logger" extend self def logger class Whatever $stdout include MiniLogger end def logger def log(message) @logger ||= open("whatever.log", "w") logger.puts "%s: %s" % end [ Time.now.strftime("%D %H:%M:%S"), def initialize message ] log "Called as an " + end "instance method " + end "and written to " + "a file." if __FILE__ == $PROGRAM_NAME end MiniLogger.log "Called as a module method and " + end "written to $stdout." end Whatever.new MIXIN YOURSELF Better than Ruby’s module_function()
  • 73.
  • 74.
  • 75.
  • 76.
  • 77. LIMITED MAGIC Summon new error types as needed
  • 78. module Errors class BaseError < RuntimeError; end def self.const_missing(error_name) if error_name.to_s =~ /wErrorz/ const_set(error_name, Class.new(BaseError)) else super end end end p Errors::SaveError LIMITED MAGIC Summon new error types as needed
  • 79. SOME EXAMPLES Bridging the theory to implementation gap
  • 80. SOME EXAMPLES Bridging the theory to implementation gap
  • 81. A BIT TOO CLEVER If RDoc can’t read it, it’s probably too clever
  • 82. require "ostruct" class << Config = OpenStruct.new def update_from_config_file(path = config_file) eval <<-END_UPDATE config = self #{File.read(path)} config END_UPDATE end # ... end Config.config_file = "config.rb" Config.update_from_config_file A BIT TOO CLEVER If RDoc can’t read it, it’s probably too clever
  • 83. require "ostruct" class << Config = OpenStruct.new def update_from_config_file(path = config_file) eval <<-END_UPDATE config = self #{File.read(path)} config.command = "ls" config config.retries = 42 END_UPDATE # ... end # ... end Config.config_file = "config.rb" Config.update_from_config_file A BIT TOO CLEVER If RDoc can’t read it, it’s probably too clever
  • 84. LESS MAGIC RDoc and I can both read it now
  • 85. require "ostruct" # These extra methods are mixed into the OpenStruct stored in Config. module Configured # This method loads configuration settings from a plain Ruby file. def update_from_config_file(path = config_file) eval <<-END_UPDATE config = self #{File.read(path)} config END_UPDATE end # ... end # This constant holds all global configuration, see Configured for details. Config = OpenStruct.new.extend(Configured) LESS MAGIC RDoc and I can both read it now
  • 86.
  • 87.
  • 88.
  • 89.
  • 90. WITH CLASS METHODS A classic pattern made popular by Rails
  • 91. module DoubleMixin module ClassMethods # ... end module InstanceMethods # ... end def self.included(receiver) receiver.extend(ClassMethods) receiver.send(:include, InstanceMethods) end end WITH CLASS METHODS A classic pattern made popular by Rails
  • 92.
  • 93.
  • 94.
  • 95.
  • 96. LABELING OBJECTS You can use a do-nothing module as a type
  • 97. module DRb # ... module DRbUndumped def _dump(dummy) # :nodoc: raise TypeError, 'can't dump' end end # ... class DRbMessage # ... def dump(obj, error=false) # :nodoc: obj = make_proxy(obj, error) if obj.kind_of? DRbUndumped # ... end # ... end # ... end LABELING OBJECTS You can use a do-nothing module as a type
  • 98. OBJECT EDITING Using hooks to edit objects
  • 99. p "ruby".strip!. capitalize! # NoMethodError: # undefined method # `capitalize!' for # nil:NilClass OBJECT EDITING Using hooks to edit objects
  • 100. module SafelyChainable def self.extended(singleton) singleton.methods.grep(/w!z/). each do |bang| p "ruby".strip!. singleton.instance_eval <<-END_RUBY def #{bang} capitalize! super self # NoMethodError: end # undefined method END_RUBY # `capitalize!' for end # nil:NilClass end end p "ruby".extend(SafelyChainable). strip!.capitalize! OBJECT EDITING Using hooks to edit objects
  • 103. SUMMARY Master Ruby’s method lookup; it’s worth the effort
  • 104. SUMMARY Master Ruby’s method lookup; it’s worth the effort Modules are a terrific at limiting the scope of magic
  • 105. SUMMARY Master Ruby’s method lookup; it’s worth the effort Modules are a terrific at limiting the scope of magic Remember, modules can modify individual objects
  • 106. SUMMARY Master Ruby’s method lookup; it’s worth the effort Modules are a terrific at limiting the scope of magic Remember, modules can modify individual objects Try replacing some inheritance with extend()
  • 107.

Notes de l'éditeur

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n