SlideShare a Scribd company logo
1 of 20
REUSABLE RUBY
     ROUTE 9 RUBY GROUP – JUNE 20, 2012



                BLAKE CARLSON
     BLAKE@COIN-OPERATED.NET   • @SKINANDBONES
GITHUB.COM/SKINANDBONES • LINKEDIN.COM/IN/BLAKECARLSON
WHY GO           REUSABLE?
                                    sloth love
                                  reusable ruby
‣ D-R-Y
‣ Maintainability
‣ Leads to better solutions
‣ Make large projects
  adaptable to change
‣ Your co-workers will love you
‣ Make gems, share code
OUR REUSABLE RUBY
          TOOLBOX*
            * this list is not everything, okay




‣ Inheritance
‣ Modules
‣ Composition
‣ Gems & Bundler
STAY      CLASSY RUBY

‣ Class inheritance
‣ ActiveRecord, ActionController,
  etc.
‣ Meant for things that can be
  instantiated or inherited
‣ Sorry, NO Interfaces or Abstract
  Classes in Ruby   (sad face?)
WE ♥ MODULES
‣ Namespaces
‣ Inject a bucket o’ instance methods into
  something else
‣ The included callback
‣ ActiveSupport::Concern
‣ Testing
‣ Pitfalls
MODULES: NAMESPACES


 # Namespaces
 module Foo
  class Widget
   # ... one thing ...
  end
 end

 module Bar
  class Widget
   # ... something else ...
  end
 end

 x = Foo::Widget.new
 y = Bar::Widget.new
MODULES: METHOD INJECTION

module Sluggable

 def generate_slug(str)
  str.to_s.strip.downcase.gsub(/[^a-z0-9s]/, '').gsub(/s+/, '-')
 end

end

class Post < ActiveRecord::Base
 include Sluggable

 before_validation :update_slug

 private

 def update_slug
  self.slug = generate_slug(title)
 end

end

# Note (1): this is a super naive solution
# Note (2): check out the stringex gem for things like String#to_url.
MODULES: THE BASICS

Let’s make generate_slug available to all AR models

Put this code into a file like lib/sluggable.rb ...

         module Sluggable
          # ...
         end

         ActiveRecord::Base.send :include, Sluggable



Somewhere, like in config/initializers ...

         require 'sluggable'
MODULES: COMMON IDIOMS

 module Sluggable
  module ClassMethods
   def find_by_slug(str)
    # ...
   end
  end

  module InstanceMethods
   def generate_slug(str)
    # ...
   end

   private

   def update_slug
    # ...
   end
  end

  def self.included(base)
   base.extend          ClassMethods
   base.send :include,    InstanceMethods
   base.before_validation :update_slug
  end
 end
ACTIVESUPPORT::CONCERN
                              Bring THE PRETTY
                       require 'active_support/concern'

                       module Sluggable
                        extend ActiveSupport::Concern

                         included do
                           before_validation :update_slug
                         end

                         module ClassMethods
                          def find_by_slug(str)
                           # ...
                          end
                         end

                         private

                        def update_slug
                         # ...
                        end
                       end


https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb
ACTIVESUPPORT::CONCERN
               What about module dependencies?
           module Foo
            def self.included(base)
             base.class_eval do
              def self.method_injected_by_foo
                # ...
              end
             end
            end
           end

           module Bar
            def self.included(base)
             base.method_injected_by_foo
            end
           end

           class Host
            include Foo # We need to include this dependency for Bar
            include Bar # Bar is the module that Host really needs
           end



https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb
ACTIVESUPPORT::CONCERN
       require 'active_support/concern'

       module Foo
        extend ActiveSupport::Concern
        included do
          class_eval do
           def self.method_injected_by_foo
             # ...
           end
          end
        end
       end

       module Bar
        extend ActiveSupport::Concern
        include Foo

        included do
          self.method_injected_by_foo
        end
       end

       class Host
        include Bar # works, Bar takes care now of its dependencies
       end



https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb
MODULES: TESTING
Test just the module, stub aggressively, use a Dummy class
         # sluggable_test.rb
         require 'spec_helper'

         class Dummy
          include ActiveModel::Validations
          extend ActiveModel::Callbacks
          include Sluggable

          define_model_callbacks :validation

          attr_accessor :title, :slug

          def initialize(title)
           self.title = title
          end
         end

         describe Sluggable do
          let(:dummy) { Dummy.new('a special title') }

          it "should update the slug when validated" do
            dummy.valid?
            dummy.slug.should eq('a-special-title')
          end
         end
MODULES: THE                DARK SIDE

 Classes that use too many modules can
 become a handful.
 1. Which module defined which method?
 2. What methods are defined in the class?
 3. Method name collisions when including
    modules
 4. You can’t reference a modularized entity, you
    must pass around the object that contains it.
MODULES: THE                DARK SIDE

‣ Over-engineering / pre-awesome-ization
‣ Which module defined which method?
‣ What methods are defined in the class?
‣ Method name collisions when including
  modules
‣ You can’t reference a modularized entity, you
  must pass around the object that contains it.
COMPOSITION:
WRANGLE THOSE MODULES



‣ A.K.A. aggregation
‣ A class is composed of several other
  classes, use delegation
Example: Composition

 class Avatar                                     class Person < ActiveRecord::Base
   attr_reader :master                              # ...

   def initialize(master)                           def avatar
     @master = master                                 @avatar ||= Avatar.new(self)
   end                                              end

   def exists?                                      def avatar_exists?
     master.has_avatar?                               avatar.exists?
   end                                              end

   def create(file)                               end
     master.update_attribute :has_avatar, true
     # thumbnail and install the given avatar
   end

   def destroy
     master.update_attribute :has_avatar, false
     # delete avatar file
   end

   # etc.
 end




http://37signals.com/svn/posts/1553-models-vs-modules
GEMS             & BUNDLER

‣ NO FEAR, make private gems to share
  code between projects
‣ Use Bundler to bootstrap gem creation
  https://github.com/radar/guides/blob/master/
  gem-development.md

‣ Use :git in your Gemfile to use gems
  directly from git repositories
  http://gembundler.com/git.html
THE END
RESOURCES

‣   http://www.fakingfantastic.com/2010/09/20/concerning-yourself-with-active-
    support-concern/

‣   http://yehudakatz.com/2009/11/12/better-ruby-idioms/

‣   http://metabates.com/2011/02/07/building-interfaces-and-abstract-classes-in-ruby/

‣   http://37signals.com/svn/posts/1553-models-vs-modules

‣   http://andrzejonsoftware.blogspot.com/2011/01/code-reuse-in-ruby-why-
    composition-is.html

‣   https://github.com/rails/rails/blob/master/activesupport/lib/active_support/
    concern.rb

‣   https://github.com/rails/rails/tree/master/activemodel

More Related Content

What's hot

Android Bootstrap
Android BootstrapAndroid Bootstrap
Android Bootstrapdonnfelker
 
(5) c sharp introduction_object_orientation_part_ii
(5) c sharp introduction_object_orientation_part_ii(5) c sharp introduction_object_orientation_part_ii
(5) c sharp introduction_object_orientation_part_iiNico Ludwig
 
Symfony2 Introduction Presentation
Symfony2 Introduction PresentationSymfony2 Introduction Presentation
Symfony2 Introduction PresentationNerd Tzanetopoulos
 
High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014
High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014
High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014Matthias Noback
 
Asset management with Zend Framework 2
Asset management with Zend Framework 2Asset management with Zend Framework 2
Asset management with Zend Framework 2Stefano Valle
 
Basic Oops concept of PHP
Basic Oops concept of PHPBasic Oops concept of PHP
Basic Oops concept of PHPRohan Sharma
 
13 java beans
13 java beans13 java beans
13 java beanssnopteck
 
Migrating PriceChirp to Rails 3.0: The Pain Points
Migrating PriceChirp to Rails 3.0: The Pain PointsMigrating PriceChirp to Rails 3.0: The Pain Points
Migrating PriceChirp to Rails 3.0: The Pain PointsSteven Evatt
 
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]Raul Fraile
 
Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)andrewnacin
 
O que há de novo no Rails 3
O que há de novo no Rails 3O que há de novo no Rails 3
O que há de novo no Rails 3Hugo Baraúna
 
Intro to Joomla Development
Intro to Joomla DevelopmentIntro to Joomla Development
Intro to Joomla DevelopmentAlex Andreae
 
Java Course 14: Beans, Applets, GUI
Java Course 14: Beans, Applets, GUIJava Course 14: Beans, Applets, GUI
Java Course 14: Beans, Applets, GUIAnton Keks
 
Adapter 2pp
Adapter 2ppAdapter 2pp
Adapter 2pprajjani
 

What's hot (19)

Android Bootstrap
Android BootstrapAndroid Bootstrap
Android Bootstrap
 
(5) c sharp introduction_object_orientation_part_ii
(5) c sharp introduction_object_orientation_part_ii(5) c sharp introduction_object_orientation_part_ii
(5) c sharp introduction_object_orientation_part_ii
 
Symfony2 Introduction Presentation
Symfony2 Introduction PresentationSymfony2 Introduction Presentation
Symfony2 Introduction Presentation
 
High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014
High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014
High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014
 
Introduction Php
Introduction PhpIntroduction Php
Introduction Php
 
Asset management with Zend Framework 2
Asset management with Zend Framework 2Asset management with Zend Framework 2
Asset management with Zend Framework 2
 
Basic Oops concept of PHP
Basic Oops concept of PHPBasic Oops concept of PHP
Basic Oops concept of PHP
 
13 java beans
13 java beans13 java beans
13 java beans
 
Migrating PriceChirp to Rails 3.0: The Pain Points
Migrating PriceChirp to Rails 3.0: The Pain PointsMigrating PriceChirp to Rails 3.0: The Pain Points
Migrating PriceChirp to Rails 3.0: The Pain Points
 
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]
 
14 mvc
14 mvc14 mvc
14 mvc
 
Sf2 wtf
Sf2 wtfSf2 wtf
Sf2 wtf
 
Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)
 
O que há de novo no Rails 3
O que há de novo no Rails 3O que há de novo no Rails 3
O que há de novo no Rails 3
 
Intro to Joomla Development
Intro to Joomla DevelopmentIntro to Joomla Development
Intro to Joomla Development
 
Java Course 14: Beans, Applets, GUI
Java Course 14: Beans, Applets, GUIJava Course 14: Beans, Applets, GUI
Java Course 14: Beans, Applets, GUI
 
Adapter 2pp
Adapter 2ppAdapter 2pp
Adapter 2pp
 
Debugging on rails
Debugging on railsDebugging on rails
Debugging on rails
 
Introduction To Web Beans
Introduction To Web BeansIntroduction To Web Beans
Introduction To Web Beans
 

Similar to Reusable Ruby Techniques

The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014Matthias Noback
 
The Dark Art of Rails Plugins (2008)
The Dark Art of Rails Plugins (2008)The Dark Art of Rails Plugins (2008)
The Dark Art of Rails Plugins (2008)lazyatom
 
Classboxes, nested methods, and real private methods
Classboxes, nested methods, and real private methodsClassboxes, nested methods, and real private methods
Classboxes, nested methods, and real private methodsShugo Maeda
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet CampPuppet
 
Creational pattern 2
Creational pattern 2Creational pattern 2
Creational pattern 2Naga Muruga
 
Metaprogramming Rails
Metaprogramming RailsMetaprogramming Rails
Metaprogramming RailsJustus Eapen
 
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
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Dependency injection in scala
Dependency injection in scalaDependency injection in scala
Dependency injection in scalaMichal Bigos
 
Webpack: your final module bundler
Webpack: your final module bundlerWebpack: your final module bundler
Webpack: your final module bundlerAndrea Giannantonio
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - TryoutMatthias Noback
 
Advanced Node.JS Meetup
Advanced Node.JS MeetupAdvanced Node.JS Meetup
Advanced Node.JS MeetupLINAGORA
 
Introduction to OSGi
Introduction to OSGiIntroduction to OSGi
Introduction to OSGipradeepfn
 
Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not JavaChris Adamson
 
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...bobmcwhirter
 
Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Workhorse Computing
 
Dependency Injection for PHP
Dependency Injection for PHPDependency Injection for PHP
Dependency Injection for PHPmtoppa
 
Ruby for C# Developers
Ruby for C# DevelopersRuby for C# Developers
Ruby for C# DevelopersCory Foy
 

Similar to Reusable Ruby Techniques (20)

The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014
 
The Dark Art of Rails Plugins (2008)
The Dark Art of Rails Plugins (2008)The Dark Art of Rails Plugins (2008)
The Dark Art of Rails Plugins (2008)
 
Classboxes, nested methods, and real private methods
Classboxes, nested methods, and real private methodsClassboxes, nested methods, and real private methods
Classboxes, nested methods, and real private methods
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
 
Creational pattern 2
Creational pattern 2Creational pattern 2
Creational pattern 2
 
Metaprogramming Rails
Metaprogramming RailsMetaprogramming Rails
Metaprogramming 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
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Dependency injection in scala
Dependency injection in scalaDependency injection in scala
Dependency injection in scala
 
Webpack: your final module bundler
Webpack: your final module bundlerWebpack: your final module bundler
Webpack: your final module bundler
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - Tryout
 
Advanced Node.JS Meetup
Advanced Node.JS MeetupAdvanced Node.JS Meetup
Advanced Node.JS Meetup
 
Introduction to OSGi
Introduction to OSGiIntroduction to OSGi
Introduction to OSGi
 
Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not Java
 
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
 
Git submodule
Git submoduleGit submodule
Git submodule
 
Only oop
Only oopOnly oop
Only oop
 
Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.
 
Dependency Injection for PHP
Dependency Injection for PHPDependency Injection for PHP
Dependency Injection for PHP
 
Ruby for C# Developers
Ruby for C# DevelopersRuby for C# Developers
Ruby for C# Developers
 

Recently uploaded

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
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
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
 
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
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
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
 
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
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
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
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
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
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
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
 
[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
 

Recently uploaded (20)

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...
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
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
 
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
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
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...
 
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)
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
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
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
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
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
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
 
[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
 

Reusable Ruby Techniques

  • 1. REUSABLE RUBY ROUTE 9 RUBY GROUP – JUNE 20, 2012 BLAKE CARLSON BLAKE@COIN-OPERATED.NET • @SKINANDBONES GITHUB.COM/SKINANDBONES • LINKEDIN.COM/IN/BLAKECARLSON
  • 2. WHY GO REUSABLE? sloth love reusable ruby ‣ D-R-Y ‣ Maintainability ‣ Leads to better solutions ‣ Make large projects adaptable to change ‣ Your co-workers will love you ‣ Make gems, share code
  • 3. OUR REUSABLE RUBY TOOLBOX* * this list is not everything, okay ‣ Inheritance ‣ Modules ‣ Composition ‣ Gems & Bundler
  • 4. STAY CLASSY RUBY ‣ Class inheritance ‣ ActiveRecord, ActionController, etc. ‣ Meant for things that can be instantiated or inherited ‣ Sorry, NO Interfaces or Abstract Classes in Ruby (sad face?)
  • 5. WE ♥ MODULES ‣ Namespaces ‣ Inject a bucket o’ instance methods into something else ‣ The included callback ‣ ActiveSupport::Concern ‣ Testing ‣ Pitfalls
  • 6. MODULES: NAMESPACES # Namespaces module Foo class Widget # ... one thing ... end end module Bar class Widget # ... something else ... end end x = Foo::Widget.new y = Bar::Widget.new
  • 7. MODULES: METHOD INJECTION module Sluggable def generate_slug(str) str.to_s.strip.downcase.gsub(/[^a-z0-9s]/, '').gsub(/s+/, '-') end end class Post < ActiveRecord::Base include Sluggable before_validation :update_slug private def update_slug self.slug = generate_slug(title) end end # Note (1): this is a super naive solution # Note (2): check out the stringex gem for things like String#to_url.
  • 8. MODULES: THE BASICS Let’s make generate_slug available to all AR models Put this code into a file like lib/sluggable.rb ... module Sluggable # ... end ActiveRecord::Base.send :include, Sluggable Somewhere, like in config/initializers ... require 'sluggable'
  • 9. MODULES: COMMON IDIOMS module Sluggable module ClassMethods def find_by_slug(str) # ... end end module InstanceMethods def generate_slug(str) # ... end private def update_slug # ... end end def self.included(base) base.extend ClassMethods base.send :include, InstanceMethods base.before_validation :update_slug end end
  • 10. ACTIVESUPPORT::CONCERN Bring THE PRETTY require 'active_support/concern' module Sluggable extend ActiveSupport::Concern included do before_validation :update_slug end module ClassMethods def find_by_slug(str) # ... end end private def update_slug # ... end end https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb
  • 11. ACTIVESUPPORT::CONCERN What about module dependencies? module Foo def self.included(base) base.class_eval do def self.method_injected_by_foo # ... end end end end module Bar def self.included(base) base.method_injected_by_foo end end class Host include Foo # We need to include this dependency for Bar include Bar # Bar is the module that Host really needs end https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb
  • 12. ACTIVESUPPORT::CONCERN require 'active_support/concern' module Foo extend ActiveSupport::Concern included do class_eval do def self.method_injected_by_foo # ... end end end end module Bar extend ActiveSupport::Concern include Foo included do self.method_injected_by_foo end end class Host include Bar # works, Bar takes care now of its dependencies end https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb
  • 13. MODULES: TESTING Test just the module, stub aggressively, use a Dummy class # sluggable_test.rb require 'spec_helper' class Dummy include ActiveModel::Validations extend ActiveModel::Callbacks include Sluggable define_model_callbacks :validation attr_accessor :title, :slug def initialize(title) self.title = title end end describe Sluggable do let(:dummy) { Dummy.new('a special title') } it "should update the slug when validated" do dummy.valid? dummy.slug.should eq('a-special-title') end end
  • 14. MODULES: THE DARK SIDE Classes that use too many modules can become a handful. 1. Which module defined which method? 2. What methods are defined in the class? 3. Method name collisions when including modules 4. You can’t reference a modularized entity, you must pass around the object that contains it.
  • 15. MODULES: THE DARK SIDE ‣ Over-engineering / pre-awesome-ization ‣ Which module defined which method? ‣ What methods are defined in the class? ‣ Method name collisions when including modules ‣ You can’t reference a modularized entity, you must pass around the object that contains it.
  • 16. COMPOSITION: WRANGLE THOSE MODULES ‣ A.K.A. aggregation ‣ A class is composed of several other classes, use delegation
  • 17. Example: Composition class Avatar class Person < ActiveRecord::Base attr_reader :master # ... def initialize(master) def avatar @master = master @avatar ||= Avatar.new(self) end end def exists? def avatar_exists? master.has_avatar? avatar.exists? end end def create(file) end master.update_attribute :has_avatar, true # thumbnail and install the given avatar end def destroy master.update_attribute :has_avatar, false # delete avatar file end # etc. end http://37signals.com/svn/posts/1553-models-vs-modules
  • 18. GEMS & BUNDLER ‣ NO FEAR, make private gems to share code between projects ‣ Use Bundler to bootstrap gem creation https://github.com/radar/guides/blob/master/ gem-development.md ‣ Use :git in your Gemfile to use gems directly from git repositories http://gembundler.com/git.html
  • 20. RESOURCES ‣ http://www.fakingfantastic.com/2010/09/20/concerning-yourself-with-active- support-concern/ ‣ http://yehudakatz.com/2009/11/12/better-ruby-idioms/ ‣ http://metabates.com/2011/02/07/building-interfaces-and-abstract-classes-in-ruby/ ‣ http://37signals.com/svn/posts/1553-models-vs-modules ‣ http://andrzejonsoftware.blogspot.com/2011/01/code-reuse-in-ruby-why- composition-is.html ‣ https://github.com/rails/rails/blob/master/activesupport/lib/active_support/ concern.rb ‣ https://github.com/rails/rails/tree/master/activemodel

Editor's Notes

  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