SlideShare une entreprise Scribd logo
1  sur  103
But the Language
   Supports it
aakash
dharmadhikari
aakash
@aakashd
niranjan paranjape
achamian
@niranjan_p
Engineering

http://github.com/c42
GOTO :context
design discussion
debate
rational arguments
defensive arguments
but the language
   supports it
really?
OO/Ruby
library vs. domain
mechanic
maturity of the team
GOTO :begin
raise “it should have jumped to the next topic”
class Species
  attr_accessor :type
  HUMAN = "human"
  # some code
  def is_human?
    self.type == Species::HUMAN
  end
end
class GodClass
  def environment_to_support(species)
    case
    when species.is_human?
      {:feeds_on => ["Plants", "Meat"],
         :required_elements_in_atmosphere => ["Oxygen", "Nitrogen"]}
    when species.is_babel_fish?
      {:feeds_on => "Brain wave",
         :required_elements_in_atmosphere => []}
    # so on
    end
  end
end
i love switch
tell don’t ask
class BabelFish < Species
  def environmental_necessities
    {:feeds_on => "Brain wave",
      :required_elements_in_atmosphere => []}
  end
end

class GodClass
  def environment_to_support(species)
    species.environmental_necessities
  end
end
are “?” methods evil?
class User
  def is_admin?
    self.role == :admin
  end
end


class ApplicationController < AbstractController::Base
  def require_admin_privilege
    unless current_user.is_admin?
      head :unauthorized
    end
  end
end
Back to switch
should ‘switch’ be
    banned?
so can I replace it with
if elsif elsif elsif ...
http://www.flickr.com/photos/santiagogprg/5023648200/
how about this?
class Species
  @@environmental_necessities = {
    "babel_fish" => {:feeds_on => "Brain wave"},
    "human" => {} # so on
  }

  def environmental_necessities
    @@environmental_necessities[self.type]
  end
end
Raise
class Aircraft
  def start_engine
    # try to start the engine
    raise "Unable to start engine" unless @engine.started?
  end
end
class Aircraft
  def deploy_landing_gear
    # try to deploy the landing gear
    return @landing_gear.deployed?
  end
end
class Aircraft
  def deploy_landing_gear
      # try to deploy the landing gear


      # landing gear is stuck halfway through
      raise "Prepare for crash landing" if @landing_gear.stuck?


      return @landing_gear.deployed?
  end
end
rules to raise
begin
  # some calculations
  # some network io
  # some file io
  # some magic
rescue => e
  logger.error('Run! Run! we have an error!')
end
begin
  # some calculations
  # some network io
  # some file io
  # some magic
rescue => e
  logger.error "Just logging! don't look at me like that."
  raise
end
begin
  # some calculations
  # some network io
  # some file io
  # some magic
rescue ZeroDivisionError
  # handle the zero devision exception
rescue SomeCrazyException
  # handle the crazy exception
rescue => e
  logger.error "No idea what's heppening. I'm just going
to retry in a while. #{e.message}"
end
Blind rescue missions
name = @user.first_name ? @user.first_name.capitalize : "Anonymous"
name = @user.first_name.capitalize rescue "Anonymous"
random facts


          rescue => e
   doesn’t rescue Exception
it only rescues StandardError
*args/hash
def accepts_var_args(*args)
  planet = args[0]
  no_of_moons = args[1]
  moons = args[2..(no_of_moons + 1)]
  continents = [(no_of_moons + 2)..-1]
end
large number of
   parameters
hash as the last
   argument
class Person
  def teach(arguments)
      arguments[:student].accept_skill(skill(arguments[:skill]))
  end
end


# 1.8.x
yoda.teach(:student => luke, :skill => "lightsaber")


# 1.9.2
yoda.teach(student:luke, skill:"lightsaber")


# VS
yoda.teach(luke, "lightsaber")
while we are talking
about the options hash
do not
modify options hash
or even worse
and expect invoker to
fetch data out of it post
           call
it leads to the dark side
def activate_skynet(options)
 options[:instructions] = "Eliminate John Conner"
 uri = "https://sky.net/activate".to_uri
  uri.post(options[:auth_headers])
end


options = {"Authentication" => "Basic: XXXXXXXXXXX"}
activation_status = activate_skynet(options)
next_step = options[:instructions]
private methods
readability
encapsulation
cleaner API
class BabelFish
  def translate(some_sound, to_language)
      # code for
      # detecting the language
      # of the text
      # code for
      # converting the input sound
      # into text
      # code for
      # generating text
      # in target language
      # code for
      # convertin text
      # to speach in to_language
  end
end
class BabelFish
  def translate(sound, to_lang)
    from_lang = detect_language(sound)
    from_text = convert_to_text(from_lang,sound)
    to_text = translate_text(from_lang, to_lang, from_text)
    return text_to_speach(to_text, to_lang)
  end

  private
  def detect_language(sound)
    # some code
  end

  def convert_to_text(language,sound)
    # some code
  end

  def translate_text(from, to, text)
    # some code
  end

  def text_to_speach(text,language)
    # some code
  end
end
then why not?
probably they don’t
   belong here
what’s the alternative?
class BabelFish
  def translate(sound_data, to_language)

Sound.new(sound_data).to_text.translate(to_
language).to_sound
  end
end

class Sound #:nodoc:
  # code
end

class Language #:nodoc:
  # code
end

class Script #:nodoc:
  #code
end
Class#new as factory
new is just a method
can work as a factory
few things to keep in
        mind
return the same type
don’t return nil
don’t raise an
 exception
http://blog.sidu.in/2007/12/rubys-new-as-factory.html
class methods
where is my object?
general belief
static methods are
       BAD
can’t inherit
can’t be abstract
can’t be polymorphic
hard to test
threading issues
does the rule of thumb
    apply to Ruby?
ruby class methods are
       not static
Ruby class methods are
 way more elegant &
       powerful
class Foo
  def self.say
    p "#{self.name} says hi"
  end
end

class Bar < Foo
end

Foo.say #=> "Foo says hi"
Bar.say #=> "Bar says hi"
class Foo
  def self.say
      p "#{self.name} says hi"
  end
end


class Bar < Foo
  def self.say
      super
      p "and welcomes you to ruby conf"
  end
end


Foo.say #=> "Foo says hi"
Bar.say #=> "Bar says hi" n "and welcomes you to ruby conf"
easy to test
ActiveRecord::Base.find
methods on instance of
    a class Class
def self.# not so bad
as long as it belongs
class Company
  def sort_emplyees(all_employees)
    all_employees.sort_by(&:salary)
  end
end
metaprogramming
random facts

       alias_method
 creates a deep clone of a
method it’s not equivalent to
          delegate
conclusion
try new things
be nice to people
who’ll inherit your
       code
write tests
42
  Aakash Dharmadhikari           Niranjan Paranjape



http://twitter.com/aakashd   http://twitter.com/niranjan_p

https://github.com/aakashd https://github.com/achamian

Contenu connexe

Tendances

Metaprogramming
MetaprogrammingMetaprogramming
Metaprogrammingjoshbuddy
 
Learn Ruby 2011 - Session 5 - Looking for a Rescue
Learn Ruby 2011 - Session 5 - Looking for a RescueLearn Ruby 2011 - Session 5 - Looking for a Rescue
Learn Ruby 2011 - Session 5 - Looking for a RescueJames Thompson
 
Ruby Programming Introduction
Ruby Programming IntroductionRuby Programming Introduction
Ruby Programming IntroductionAnthony Brown
 
Ruby from zero to hero
Ruby from zero to heroRuby from zero to hero
Ruby from zero to heroDiego Lemos
 
Perl 5.10
Perl 5.10Perl 5.10
Perl 5.10acme
 
Introduction to writing readable and maintainable Perl
Introduction to writing readable and maintainable PerlIntroduction to writing readable and maintainable Perl
Introduction to writing readable and maintainable PerlAlex Balhatchet
 
What You Need to Know About Lambdas - Jamie Allen (Typesafe)
What You Need to Know About Lambdas - Jamie Allen (Typesafe)What You Need to Know About Lambdas - Jamie Allen (Typesafe)
What You Need to Know About Lambdas - Jamie Allen (Typesafe)jaxLondonConference
 
Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)mircodotta
 
Getting started with Perl XS and Inline::C
Getting started with Perl XS and Inline::CGetting started with Perl XS and Inline::C
Getting started with Perl XS and Inline::Cdaoswald
 
Ruby For Java Programmers
Ruby For Java ProgrammersRuby For Java Programmers
Ruby For Java ProgrammersMike Bowler
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.VimLin Yo-An
 
Ruby Programming Language - Introduction
Ruby Programming Language - IntroductionRuby Programming Language - Introduction
Ruby Programming Language - IntroductionKwangshin Oh
 
Ruby for Java Developers
Ruby for Java DevelopersRuby for Java Developers
Ruby for Java DevelopersRobert Reiz
 
Ruby Basics
Ruby BasicsRuby Basics
Ruby BasicsSHC
 
Best Practices for Quality Code
Best Practices for Quality CodeBest Practices for Quality Code
Best Practices for Quality CodeSercan Degirmenci
 
Red Flags in Programming
Red Flags in ProgrammingRed Flags in Programming
Red Flags in ProgrammingxSawyer
 

Tendances (20)

The Joy Of Ruby
The Joy Of RubyThe Joy Of Ruby
The Joy Of Ruby
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogramming
 
Learn Ruby 2011 - Session 5 - Looking for a Rescue
Learn Ruby 2011 - Session 5 - Looking for a RescueLearn Ruby 2011 - Session 5 - Looking for a Rescue
Learn Ruby 2011 - Session 5 - Looking for a Rescue
 
Ruby Programming Introduction
Ruby Programming IntroductionRuby Programming Introduction
Ruby Programming Introduction
 
Ruby from zero to hero
Ruby from zero to heroRuby from zero to hero
Ruby from zero to hero
 
Perl 5.10
Perl 5.10Perl 5.10
Perl 5.10
 
Introduction to writing readable and maintainable Perl
Introduction to writing readable and maintainable PerlIntroduction to writing readable and maintainable Perl
Introduction to writing readable and maintainable Perl
 
Perl Moderno
Perl ModernoPerl Moderno
Perl Moderno
 
What You Need to Know About Lambdas - Jamie Allen (Typesafe)
What You Need to Know About Lambdas - Jamie Allen (Typesafe)What You Need to Know About Lambdas - Jamie Allen (Typesafe)
What You Need to Know About Lambdas - Jamie Allen (Typesafe)
 
Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)
 
Getting started with Perl XS and Inline::C
Getting started with Perl XS and Inline::CGetting started with Perl XS and Inline::C
Getting started with Perl XS and Inline::C
 
Ruby For Java Programmers
Ruby For Java ProgrammersRuby For Java Programmers
Ruby For Java Programmers
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.Vim
 
Ruby Programming Language - Introduction
Ruby Programming Language - IntroductionRuby Programming Language - Introduction
Ruby Programming Language - Introduction
 
Elixir for rubysts
Elixir for rubystsElixir for rubysts
Elixir for rubysts
 
Ruby for Java Developers
Ruby for Java DevelopersRuby for Java Developers
Ruby for Java Developers
 
Ruby Basics
Ruby BasicsRuby Basics
Ruby Basics
 
Best Practices for Quality Code
Best Practices for Quality CodeBest Practices for Quality Code
Best Practices for Quality Code
 
Red Flags in Programming
Red Flags in ProgrammingRed Flags in Programming
Red Flags in Programming
 
Iq rails
Iq railsIq rails
Iq rails
 

Similaire à But the Language Supports OO/Ruby Design Discussion/TITLE

Similaire à But the Language Supports OO/Ruby Design Discussion/TITLE (20)

Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
 
RSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversRSpec 3.0: Under the Covers
RSpec 3.0: Under the Covers
 
Ruby
RubyRuby
Ruby
 
Ruby Intro {spection}
Ruby Intro {spection}Ruby Intro {spection}
Ruby Intro {spection}
 
ppt7
ppt7ppt7
ppt7
 
ppt2
ppt2ppt2
ppt2
 
name name2 n
name name2 nname name2 n
name name2 n
 
test ppt
test ppttest ppt
test ppt
 
name name2 n
name name2 nname name2 n
name name2 n
 
ppt17
ppt17ppt17
ppt17
 
ppt30
ppt30ppt30
ppt30
 
name name2 n2.ppt
name name2 n2.pptname name2 n2.ppt
name name2 n2.ppt
 
ppt18
ppt18ppt18
ppt18
 
Ruby for Perl Programmers
Ruby for Perl ProgrammersRuby for Perl Programmers
Ruby for Perl Programmers
 
ppt9
ppt9ppt9
ppt9
 
name name2 n2
name name2 n2name name2 n2
name name2 n2
 
ppt21
ppt21ppt21
ppt21
 
name name2 n
name name2 nname name2 n
name name2 n
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Write your Ruby in Style
Write your Ruby in StyleWrite your Ruby in Style
Write your Ruby in Style
 

Dernier

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
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
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
 
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
 
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
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
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
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
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
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
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
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
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
 

Dernier (20)

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
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
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
 
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
 
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
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
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
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
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
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
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
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
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
 

But the Language Supports OO/Ruby Design Discussion/TITLE

Notes de l'éditeur

  1. Good morning everyone and thank you for being here. \n
  2. \n
  3. I do my open source here\n
  4. Albeit intermittently I tweet here\n
  5. This is Niranjan\n
  6. you can find his open source contribution here\n
  7. he tweets here\n
  8. \n
  9. \n
  10. criticising\ndiscuss design or architecture\ntrivial part of the system or whole codebase\n\nIf there is one common thing that we all love, it&amp;#x2019;s criticising code. We discuss the design or if you excuse me &amp;#x201C;the architecture&amp;#x201D; of the system we are working on. It may be a trivial part of the system or it might impact the whole codebase. The fact is we like to talk.\n
  11. Some time these discussions lead to a debate\n
  12. To begin with rational arguments are presented by everyone involved to justify why certain thing should or should not be done. Points are put forward, counter-points are offered and merits and demerits of various approaches are taken into consideration. This often leads to a conclusion and everyone gets back to coding. But unfortunately sometimes this doesn&amp;#x2019;t happen.\n
  13. Despite of all the odds, someone decides to stick with his solution and starts offering defensive arguments. It&amp;#x2019;s fine, we can agree to disagree. \n\nBut then there comes a time when the unspeakable is spoken.\n
  14. The language designers weren&amp;#x2019;t stupid, why can&amp;#x2019;t I use this feature when the language supports it\n
  15. \n
  16. Yes indeed, the language does support it. Language also supports writing 900 odd lines long class with 150 lines long method. Which has a switch case, for loop, 42 return statements, a few raise conditions and opening up a class like Array to add domain logic.\n\nAll these things and many more are supported by Ruby. There are places where you&amp;#x2019;ll use these features. But you shouldn&amp;#x2019;t treat everything as nail just because you are holding a hammer.\n
  17. In next 30 minutes we will talk about various things which Ruby supports, few are specific to Ruby, while other are more generic in nature. We will talk about why you need to pay attention whenever you use any of these features.\n\nIn this talk we will cover various features provided by Ruby that, while awesome, should be used with caution. Few of these features are specific to Ruby, few are language agnostic.\n
  18. Most of these constructs might seem like a norm and necessary if you have been writing lot of library code to provide a generic feature set, but while writing domain specific (production) code they can be avoided to achieve better object oriented design\n
  19. One thing I&amp;#x2019;ld like to point out is, most of this is a mechanic to achieve a better code.\n
  20. [Handoff]\n\nDepending on the maturity of team, you may use few of these construct without adding &amp;#x2018;Magic&amp;#x2019; for the fellow programmer, while you may stay away from others by instinct.\n\nWhen I say fellow developers, I am not talking about your current team but also the developers who are going to inherit your code.\n
  21. [achamian]\n\nI guess that&amp;#x2019;s enough of context let&amp;#x2019;s skip through rest of the context and jump directly to the crux of the talk\n
  22. Jumping straight into the code example.\n\nWhat&amp;#x2019;s wrong with this method:\n\nanyone?\n\nIt&amp;#x2019;s as short as a method can get.\nName expresses the intent.\nIt returns a boolean, appropriately indicated by &amp;#x201C;?&amp;#x201D; at the end as per the Ruby convention\n\nLooks perfect and it is. But it indicates a smell. Every time I write a method like this, I ask why anyone needs to know what state my object is in. The very existence of this method indicates that there&amp;#x2019;s an &amp;#x201C;if&amp;#x201D; or worse &amp;#x201C;switch&amp;#x201D; somewhere else in my code. May be something like this\n
  23. Sweet, we have a switch case. \n\nNice readable code, is it testable? Who cares?\n
  24. Now that&amp;#x2019;s a problem our small, beautiful method created for us.\n
  25. We are violating one of the basic principles of OO &amp;#x201C;tell don&amp;#x2019;t ask&amp;#x201D;. How to fix it, maybe it&amp;#x2019;s time to create a different classes for Human and BabelFish. May be something like \n
  26. \n
  27. Not always. There are places where you have to make a choice between either breaking &amp;#x201C;tell don&amp;#x2019;t ask&amp;#x201D; or pushing code to an objects where it doesn&amp;#x2019;t belong. In such cases you might be forced to expose internal state of the object to outside world. For example:\n
  28. Yes, this can be pushed into user by passing a lambda etc. but at least it is acceptable as you don&amp;#x2019;t want to push controller&amp;#x2019;s responsibility to a model\n
  29. \n
  30. While most of the places switch can be replaced with a better modelling, there are scenarios where it&amp;#x2019;s difficult to avoid switch. The only example I can think of is parsing an input from a command line\n
  31. \n
  32. \n
  33. Hmm.\n\nhttp://www.flickr.com/photos/santiagogprg/5023648200/\n
  34. \n
  35. [Handoff]\n\nNo switch, no if, no exposing the type.\n\nThe branching still exists.\n\nWhile all that is true I&amp;#x2019;ld rather leave my code with an if or a switch and make the branching explicit so as to refactor it later instead of hiding the branching behind a Hash. \n\nThis is strictly a personal preference.\n
  36. [aakashd]\n\nWhat I want to talk about raising &amp; rescuing exceptions is based on an assumption that we all know about two possible program flows; the regular flow &amp; exceptional flow. That one should not throw an exception in regular flow &amp; should use it carefully even in exceptional flow.\n
  37. \n
  38. \n
  39. But what happens when landing gear is stuck.\n
  40. One should raise an exception when the purpose of the method cannot be completed and because of that the application is left in an unknown and possible inconsistent state.\n\nIn languages like Java, exceptions are way to force user to handle a possible outcome of method invocation, which I believe is very much useful because hardly any of the developers take pain to read the documentation.\n\nAnd last but not the least is the teams or community&amp;#x2019;s conventions about using exceptions. If nothing please stick to that.\n
  41. A classic example of wrong exception handling is unqualified rescue\n\nIf you are expecting a piece of code to raise an exception, it is always better to catch that particular exception instead of catching a generic exception. \n\nIf you are forced to write an unqualified rescue because the code block you are rescuing raises a lot of exceptions, then probably that problem should be solved first. \n\n\n
  42. One of the scenario where unqualified rescue makes sense is that we just want to log the exception &amp; propagate it further.\n
  43. Another scenario where I will have an unqualified raise is when I don&amp;#x2019;t want an unexpected exception to kill the deamon process.\n\nI would handle all the known exceptions if I can, and in the end just suppress the exception after logging it.\n
  44. (Gregory Brown aka @seacreature)\n\nThere are just too many anti-patterns for rescue..\n\nAnother `clever` use of rescue is to assign default values in case of exceptions. What Gregory Brown calls as Blind Rescue Mission in his book Ruby Best Practices. The example in his book is so apt, that I have shamelessly copied the same thing.\n
  45. The writers intention here is to return a string &amp;#x201C;Anonymous&amp;#x201D; when user does not have first_name. This line of code is slightly complicated because of the ternary operator.\n
  46. Few people prefer it&amp;#x2019;s concise &amp; questionably though but cleaner version.\n\ncertainly looks a lot more cleaner but what happens when the user itself is nil. The line still succeeds &amp; tells me that the current user is Anonymous.\n
  47. [Handoff]\n
  48. [achamian]\n\nRuby supports accepting variable number of arguments or hash as a last argument of the method call. While writing a library code this comes in handy.\n
  49. But when you are dealing with non-generic code it is better not to accept the var args. Explicitly calling out list of arguments to the method might increase the method signature but it is much more readable.\n
  50. If method is accepting a huge list of parameters, say 5 or more, because of which you want to shift to switch to *args, that itself is a smell.\n\nIt might be necessary for a factory or an object builder, but other places you might want to look at that list and see if those arguments can be clubbed into one or more objects. I am not talking about DTOs here. These related parameters almost always represent some job which method under consideration is doing which can be pushed to that object itself.\n
  51. Same can be said for the hash as a last argument of the method. If the hash represents a long list of options which user may or may not pass, I can understand accepting a hash as it makes it easier to invoke method.\n\nTypical example of such options hash is any of the Rails view helper methods.\n
  52. Here the first approach looks tempting as the invocation is lot more readable than the second case. But I&amp;#x2019;ld rather wait for Matz to support such method invocations over using hashes. \n\nBetter state the number of arguments method accepts in the method signature rather than the rdoc\n
  53. \n
  54. \n
  55. Hamster\n
  56. \n
  57. \n
  58. Path to the dark side it leads to\n
  59. please don&amp;#x2019;t\n
  60. Before I put forward my opinions about private methods let&amp;#x2019;s see what the proponents of private methods say about it. The top reasons why people choose private methods are:\n
  61. \n
  62. \n
  63. \n
  64. I have twisted the implementation of BabelFish to make it more understandable for people who are not familiar with Hitchhikers Guide. So please pardon me for this stupid code.\n\nAs I said earlier, this big method is not readable &amp; to any new developer the implementation is not very clear. So let&amp;#x2019;s split this into multiple methods.\n
  65. As expected the translate method has become concise &amp; readable. The extracted methods are obviously private, as no one should be able to call detect_language or text_to_speach on BabelFish, it&amp;#x2019;s just bad API &amp; I couldn&amp;#x2019;t agree more.\n\nSo now we have a clean API, with great encapsulation &amp; all the methods are perfectly readable.\n\nIf using private methods allows me to achieve all these important qualities of a good API, why do I smell something fishy here?\n
  66. I still feel I shouldn&amp;#x2019;t have done this!\n
  67. Our BabelFish is too big &amp; doing too many things. Any implementation change, bug fixes, new functionalities will touch this one file. Not a good thing to do.\n
  68. There may not always be an alternative to private methods, but in my experience if I look hard I have generally found another hidden entity, who can take this responsibility and make the original class smaller &amp; neater.\n\nI always look at private methods as first step towards better design, the key is to observe the data private methods are manipulating. If you see a data that is being manipulated purely by private methods, you have just found the entity that is waiting to be extracted.\n\nGenerally private methods can be replaced by composition or delegation.\n
  69. Broken encapsulation\nways to communicate not to use internals\nstill I prefer it\n\nI have probably broken library level encapsulation &amp; exposed classes with public interfaces that I don&amp;#x2019;t want my users to use. But I would any day prefer this design over a well encapsulated BabelFish.\n\nThere are ways to communicate to user that these classes should not be used. Most simple but not very effective way would be to annotate the class or module as nodoc, so that the respective class or module won&amp;#x2019;t be documented.\n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. From OO design perspective I have same set of arguments against static methods that I have against private methods. In some cases static methods are worse than private methods, because they encourage procedural programming.\n\nI will repeat myself, that if you look hard you can certainly find the objects to whom you can delegate this responsibility.\n
  80. Next few slides are my personal opinions &amp; I am still figuring out things. They will be very controversial, and I won&amp;#x2019;t be surprised if everyone of you disagrees with me.\n\nIn my more than 4 years of experience with Java, class methods or static methods have become a taboo. I have heard similar nightmarish stories of statically typed languages where bunch of static methods live in their own global context &amp; cause limitless problems right from bad design, hard to test code, threading issues to erratic behavior of static members due to multiple custom class loaders.\n\nLet&amp;#x2019;s see what arguments I would have presented against static methods before I started working with Ruby.\n
  81. \n
  82. \n
  83. \n
  84. \n
  85. It suffice to say that as a rule of thumb, just stay away from static in Java world.\n
  86. But apart from the OO thingy, none of the problems stated previously hold true with Ruby.\n
  87. The ruby class methods are unfairly compared with Java static methods, when the Ruby class methods need not be static.\n\n\n
  88. \n
  89. The ruby class methods can be inherited, making them part of the class definition hierarchy if not object hierarchy. \n\nThe method is no more a non-extensible block of static code &amp; if coded well it can deliver a lot of value.\n
  90. The behavior of class methods can be extended or completely overridden, making it more reusable. If there is a logic at blueprint level but not applicable at instance level, you can effectively use class methods to DRY the code.\n
  91. The ruby class methods are as easy to test as instance methods, making the maintenance a non issue.\n
  92. ActiveRecords find method is one my most favorite example of a good class method. There will be a lot of people here who hate the kind of baggage extending activerecord pushes on simple models. But it really changed the way I used to look at class level methods, coming from Java world.\n\nWith ruby&amp;#x2019;s class methods, I am more comfortable having this as class method on my models, rather than adding boilerplate code of DAO&amp;#x2019;s.\n
  93. What I am about to say sounds slightly convoluted, but I will speak slowly. Ruby class methods are not static they are methods on an instance of a class Class\n
  94. \n
  95. \n
  96. Having a class method which does not use its state is as stupid as having an instance of Company \n
  97. [achamian]\n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n