SlideShare une entreprise Scribd logo
1  sur  41
Ruby
muito mais do que reflexivo!




fabio.kung@caelum.com.br
Reflexão

p = Person.new

p.class
# => Person

p.methods
# => [quot;instance_variablesquot;, quot;classquot;, ..., quot;to_squot;]

Person.instance_methods
# => [quot;instance_variablesquot;, ..., to_squot;]
Dinamismo
Metaprogramação
Metaprogramação
  class Aluno
  end

  marcos = Aluno.new
  marcos.respond_to? :programa # => false

  class Professor
    def ensina(aluno)
      def aluno.programa
        quot;puts 'agora sei programar'quot;
      end
    end
  end

  knuth = Professor.new
  knuth.ensina marcos

  marcos.respond_to? :programa
  # => true
  marcos.programa
  # => quot;puts 'agora sei programar'quot;
“Skilled programmers can write
better programmers than they can
              hire”
                      -- Giles Bowkett
Code as Data
User.detect { |u| u.name == 'John' && u.age == 22 }
# SELECT * FROM users WHERE users.name = 'John' AND users.age = 22


User.select { |u| [1, 2, 3, 4].include? u.id }
# SELECT * FROM users WHERE users.id IN (1,2,3,4)
ParseTree
                           class


class Person    Person     nil     scope

  def say_hi                       defn

    puts quot;hiquot;            say_hi              scope
                                    args

  end                                        block

end                                           call

                                       nil   puts    arglist

                                                      str

                                                      “hi”
ParseTree
                s(:class,
                  :Person,
class Person      nil,
                  s(:scope,
  def say_hi        s(:defn,
                       :say_hi,
    puts quot;hiquot;         s(:args),
  end                 s(:scope,
                         s(:block,
end                        s(:call,
                             nil,
                             :puts,
                             s(:arglist,
                               s(:str,
                                 quot;hiquot;))))))))
Feedback
 Editores/IDEs
class

                                           nil     scope
                                Person

                                                    defn

                                         say_hi     args     scope

                                                             block

require 'parse_tree'                                          call

                                                             puts
                                                       nil           arglist
tree = ParseTree.new.process(...)
tree[0][2][0][2]                                                      str

                                                                      “hi”
# => s(:scope,
       s(:block,
         s(:call,
           nil, :puts, s(:arglist, ...))))
SexpProcessor
class TheProcessor < SexpProcessor
  def process_call(node)
    # ...
    process node
  end

  def process_class(node)
    # ...
    process node
  end

  def process_scope(node)
    # ...
    process node
  end
end
SexpProcessor
class TheProcessor < SexpProcessor
  def process_call(node)
    # ...
                    ast = ParseTree.new.process(...)
    process node
                    new_ast = TheProcessor.new.process(ast)
  end

  def process_class(node)
    # ...
    process node
  end

  def process_scope(node)
    # ...
    process node
  end
end
class

                                             nil     scope
                                  Person

                                                      defn

                                           say_hi     args     scope

                                                               block
class RenameProcessor < SexpProcessor
                                                                call

  def process_defn(node)                                       puts
                                                         nil           arglist
    name = node.shift
                                                                        str
    args = process(node.shift)
    scope = process(node.shift)                                         “hi”

    s(:defn, :quot;new_#{name}quot;, args, scope)
  end

end
Flog
Flog shows you the most
torturous code you wrote.     class Test
                                def blah           #   11.2 =
The more painful the              a = eval quot;1+1quot;   #   1.2 + 6.0 +
code, the higher the score.       if a == 2 then   #   1.2 + 1.2 + 0.4 +
The higher the score, the           puts quot;yayquot;     #   1.2
                                  end
harder it is to test.           end
                              end
roodi
          Ruby Object Oriented Design Inferometer


•   ClassLineCountCheck

•   ClassNameCheck

•   CyclomaticComplexityBlockCheck

•   CyclomaticComplexityMethodCheck

•   EmptyRescueBodyCheck

•   MethodLineCountCheck

•   MethodNameCheck

•   ParameterNumberCheck

•   ...
merb-action-args
class Posts < Merb::Controller

  def create(post)
    # post = params[:post]
    @post = Post.new(post)
    @post.save
  end

  # ...
end
Heckle

Think you write good
tests? Not bloody likely...
Put it to the test with
heckle. It’ll put your
code into submission in
seconds.
Outros

• Reek (== roodi)
• Flay
• Rufus
• ...
Ambition
User.select { |u| u.name == 'John' && u.age == 22 }
# SELECT * FROM users WHERE users.name = 'John' AND users.age = 22
# quot;(&(name=jon)(age=21))quot;
Ambition
User.select { |u| u.name == 'John' && u.age == 22 }
# SELECT * FROM users WHERE users.name = 'John' AND users.age = 22
# quot;(&(name=jon)(age=21))quot;



User.select { |u| [1, 2, 3, 4].include? u.id }
# SELECT * FROM users WHERE users.id IN (1,2,3,4)
Ambition
User.select { |u| u.name == 'John' && u.age == 22 }
# SELECT * FROM users WHERE users.name = 'John' AND users.age = 22
# quot;(&(name=jon)(age=21))quot;



User.select { |u| [1, 2, 3, 4].include? u.id }
# SELECT * FROM users WHERE users.id IN (1,2,3,4)



User.select { |u| u.friends.name =~ /bi/ }
# SELECT * FROM users LEFT OUTER JOIN ... WHERE friends.name ~ 'bi'
Ambition
User.select { |u| u.name == 'John' && u.age == 22 }
# SELECT * FROM users WHERE users.name = 'John' AND users.age = 22
# quot;(&(name=jon)(age=21))quot;



User.select { |u| [1, 2, 3, 4].include? u.id }
# SELECT * FROM users WHERE users.id IN (1,2,3,4)



User.select { |u| u.friends.name =~ /bi/ }
# SELECT * FROM users LEFT OUTER JOIN ... WHERE friends.name ~ 'bi'



User.select { |u| ... }.sort_by { |u| u.name }
# SELECT * FROM users WHERE ... ORDER BY users.name
ParseTree Manipulation
http://martinfowler.com/dslwip/ParseTreeManipulation.html
Rfactor
                                      $$$

                                        class Banco
                                          def transfere(origem, destino, valor)
s(:class,                                   puts quot;iniciando transferenciaquot;
  :Banco,                                   puts quot;por favor, aguarde...quot;
  nil,                                      # ...
  s(:scope,                               end
  s(:block,
    s(:defn,                               def incrementa_juros(taxa)
       :transfere,                           # ...
      s(:args, :origem, :destino, :valor),end
      s(:scope,                          end
         s(:block,
           s(:call, nil, :puts, s(:arglist, s(:str, quot;iniciando transferenciaquot;))),
           s(:call, nil, :puts, s(:arglist, s(:str, quot;por favor, aguarde...quot;)))))),
    s(:defn,
       :incrementa_juros,
      s(:args, :taxa),
      s(:scope,
         s(:block, s(:nil)))))))
Ruby2Ruby
var bloco = function() {
  alert(quot;hey, I'm a functionquot;);
}

bloco.toString();
Ruby2Ruby
     var bloco = function() {
       alert(quot;hey, I'm a functionquot;);
     }

     bloco.toString();


bloco = lambda do
  puts quot;hey, I'm a blockquot;
end

bloco.to_ruby
# => quot;proc { puts(quot;hey, I'm a blockquot;) }quot;
metaprogramação: como fica
     o código gerado?
serialização de código
require 'mapreduce_enumerable'

(1..100).to_a.dmap do |item|
  item * 2
end



http://romeda.org/blog/2007/04/mapreduce-in-36-lines-of-ruby.html
Ofuscação
Ruby2Java
Ruby2Java
• rb2js: http://rb2js.rubyforge.org
• red-js: http://wiki.github.com/jessesielaff/red
JRuby
compiler2.rb
Geradores


• Gráficos
• UML
• ...
Código Nativo
       (problema)
• ruby_parser
• Ripper (1.9)
• JRuby ParseTree
Dúvidas?




                       Obrigado!
fabio.kung@caelum.com.br
    http://fabiokung.com
     twitter: fabiokung

Contenu connexe

Tendances

Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.Vim
Lin Yo-An
 

Tendances (20)

Beyond Breakpoints: Advanced Debugging with XCode
Beyond Breakpoints: Advanced Debugging with XCodeBeyond Breakpoints: Advanced Debugging with XCode
Beyond Breakpoints: Advanced Debugging with XCode
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Creating Domain Specific Languages in Python
Creating Domain Specific Languages in PythonCreating Domain Specific Languages in Python
Creating Domain Specific Languages in Python
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
Perl 6 in Context
Perl 6 in ContextPerl 6 in Context
Perl 6 in Context
 
P6 OO vs Moose (&Moo)
P6 OO vs Moose (&Moo)P6 OO vs Moose (&Moo)
P6 OO vs Moose (&Moo)
 
Clean code
Clean codeClean code
Clean code
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation Tutorial
 
Groovy presentation
Groovy presentationGroovy presentation
Groovy presentation
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
 
Pig Introduction to Pig
Pig Introduction to PigPig Introduction to Pig
Pig Introduction to Pig
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perl
 
Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.Vim
 
Wx::Perl::Smart
Wx::Perl::SmartWx::Perl::Smart
Wx::Perl::Smart
 
A limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyA limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced Ruby
 
Polyglot JVM
Polyglot JVMPolyglot JVM
Polyglot JVM
 
Headless Js Testing
Headless Js TestingHeadless Js Testing
Headless Js Testing
 

En vedette

En vedette (13)

DockerCon 2014: Thoughts on interoperable containers
DockerCon 2014: Thoughts on interoperable containersDockerCon 2014: Thoughts on interoperable containers
DockerCon 2014: Thoughts on interoperable containers
 
Ruby 2.0: to infinity... and beyond!
Ruby 2.0: to infinity... and beyond!Ruby 2.0: to infinity... and beyond!
Ruby 2.0: to infinity... and beyond!
 
Dicas e truques para ser um bom inquilino no Cloud
Dicas e truques para ser um bom inquilino no CloudDicas e truques para ser um bom inquilino no Cloud
Dicas e truques para ser um bom inquilino no Cloud
 
Linux Containers at scale: challenges in a very dense environment
Linux Containers at scale: challenges in a very dense environmentLinux Containers at scale: challenges in a very dense environment
Linux Containers at scale: challenges in a very dense environment
 
Ruby and Rails Packaging to Production
Ruby and Rails Packaging to ProductionRuby and Rails Packaging to Production
Ruby and Rails Packaging to Production
 
Greqia e lashte
Greqia e lashteGreqia e lashte
Greqia e lashte
 
LXC, Docker, security: is it safe to run applications in Linux Containers?
LXC, Docker, security: is it safe to run applications in Linux Containers?LXC, Docker, security: is it safe to run applications in Linux Containers?
LXC, Docker, security: is it safe to run applications in Linux Containers?
 
Docker, Linux Containers, and Security: Does It Add Up?
Docker, Linux Containers, and Security: Does It Add Up?Docker, Linux Containers, and Security: Does It Add Up?
Docker, Linux Containers, and Security: Does It Add Up?
 
Containers, docker, and security: state of the union (Bay Area Infracoders Me...
Containers, docker, and security: state of the union (Bay Area Infracoders Me...Containers, docker, and security: state of the union (Bay Area Infracoders Me...
Containers, docker, and security: state of the union (Bay Area Infracoders Me...
 
Containers, Docker, and Security: State Of The Union (LinuxCon and ContainerC...
Containers, Docker, and Security: State Of The Union (LinuxCon and ContainerC...Containers, Docker, and Security: State Of The Union (LinuxCon and ContainerC...
Containers, Docker, and Security: State Of The Union (LinuxCon and ContainerC...
 
Realizing Linux Containers (LXC)
Realizing Linux Containers (LXC)Realizing Linux Containers (LXC)
Realizing Linux Containers (LXC)
 
Docker introduction
Docker introductionDocker introduction
Docker introduction
 
Docker, Linux Containers (LXC), and security
Docker, Linux Containers (LXC), and securityDocker, Linux Containers (LXC), and security
Docker, Linux Containers (LXC), and security
 

Similaire à Ruby, muito mais que reflexivo

Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手
Wen-Tien Chang
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
Kang-min Liu
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
Jano Suchal
 
Metaprogramming in Ruby
Metaprogramming in RubyMetaprogramming in Ruby
Metaprogramming in Ruby
ConFoo
 

Similaire à Ruby, muito mais que reflexivo (20)

Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2ruby
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009
 
Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009Ruby presentasjon på NTNU 22 april 2009
Ruby presentasjon på NTNU 22 april 2009
 
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)
 
Active Support Core Extensions (1)
Active Support Core Extensions (1)Active Support Core Extensions (1)
Active Support Core Extensions (1)
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手
 
SWP - A Generic Language Parser
SWP - A Generic Language ParserSWP - A Generic Language Parser
SWP - A Generic Language Parser
 
Ruby quick ref
Ruby quick refRuby quick ref
Ruby quick ref
 
Groovy.pptx
Groovy.pptxGroovy.pptx
Groovy.pptx
 
Language supports it
Language supports itLanguage supports it
Language supports it
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record
 
shellScriptAlt.pptx
shellScriptAlt.pptxshellScriptAlt.pptx
shellScriptAlt.pptx
 
Metaprogramming in Ruby
Metaprogramming in RubyMetaprogramming in Ruby
Metaprogramming in Ruby
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogramming
 
Ruby training day1
Ruby training day1Ruby training day1
Ruby training day1
 
Groovy
GroovyGroovy
Groovy
 

Plus de Fabio Kung

Plus de Fabio Kung (8)

Cloud IaaS - Detalhes da Infraestrutura como Serviço
Cloud IaaS - Detalhes da Infraestrutura como ServiçoCloud IaaS - Detalhes da Infraestrutura como Serviço
Cloud IaaS - Detalhes da Infraestrutura como Serviço
 
Usando o Cloud
Usando o CloudUsando o Cloud
Usando o Cloud
 
Storage para virtualização
Storage para virtualizaçãoStorage para virtualização
Storage para virtualização
 
Automacao devops
Automacao devopsAutomacao devops
Automacao devops
 
DSLs Internas e Ruby
DSLs Internas e RubyDSLs Internas e Ruby
DSLs Internas e Ruby
 
Onde mora a produtividade do Ruby on Rails?
Onde mora a produtividade do Ruby on Rails?Onde mora a produtividade do Ruby on Rails?
Onde mora a produtividade do Ruby on Rails?
 
SOA não precisa ser buzzword
SOA não precisa ser buzzwordSOA não precisa ser buzzword
SOA não precisa ser buzzword
 
JRuby on Rails
JRuby on RailsJRuby on Rails
JRuby on Rails
 

Dernier

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Dernier (20)

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 

Ruby, muito mais que reflexivo

  • 1. Ruby muito mais do que reflexivo! fabio.kung@caelum.com.br
  • 2.
  • 3. Reflexão p = Person.new p.class # => Person p.methods # => [quot;instance_variablesquot;, quot;classquot;, ..., quot;to_squot;] Person.instance_methods # => [quot;instance_variablesquot;, ..., to_squot;]
  • 6. Metaprogramação class Aluno end marcos = Aluno.new marcos.respond_to? :programa # => false class Professor def ensina(aluno) def aluno.programa quot;puts 'agora sei programar'quot; end end end knuth = Professor.new knuth.ensina marcos marcos.respond_to? :programa # => true marcos.programa # => quot;puts 'agora sei programar'quot;
  • 7. “Skilled programmers can write better programmers than they can hire” -- Giles Bowkett
  • 9. User.detect { |u| u.name == 'John' && u.age == 22 } # SELECT * FROM users WHERE users.name = 'John' AND users.age = 22 User.select { |u| [1, 2, 3, 4].include? u.id } # SELECT * FROM users WHERE users.id IN (1,2,3,4)
  • 10. ParseTree class class Person Person nil scope def say_hi defn puts quot;hiquot; say_hi scope args end block end call nil puts arglist str “hi”
  • 11. ParseTree s(:class, :Person, class Person nil, s(:scope, def say_hi s(:defn, :say_hi, puts quot;hiquot; s(:args), end s(:scope, s(:block, end s(:call, nil, :puts, s(:arglist, s(:str, quot;hiquot;))))))))
  • 13. class nil scope Person defn say_hi args scope block require 'parse_tree' call puts nil arglist tree = ParseTree.new.process(...) tree[0][2][0][2] str “hi” # => s(:scope, s(:block, s(:call, nil, :puts, s(:arglist, ...))))
  • 14. SexpProcessor class TheProcessor < SexpProcessor def process_call(node) # ... process node end def process_class(node) # ... process node end def process_scope(node) # ... process node end end
  • 15. SexpProcessor class TheProcessor < SexpProcessor def process_call(node) # ... ast = ParseTree.new.process(...) process node new_ast = TheProcessor.new.process(ast) end def process_class(node) # ... process node end def process_scope(node) # ... process node end end
  • 16. class nil scope Person defn say_hi args scope block class RenameProcessor < SexpProcessor call def process_defn(node) puts nil arglist name = node.shift str args = process(node.shift) scope = process(node.shift) “hi” s(:defn, :quot;new_#{name}quot;, args, scope) end end
  • 17. Flog Flog shows you the most torturous code you wrote. class Test   def blah         # 11.2 = The more painful the     a = eval quot;1+1quot; # 1.2 + 6.0 + code, the higher the score.     if a == 2 then # 1.2 + 1.2 + 0.4 + The higher the score, the       puts quot;yayquot;   # 1.2     end harder it is to test.   end end
  • 18. roodi Ruby Object Oriented Design Inferometer • ClassLineCountCheck • ClassNameCheck • CyclomaticComplexityBlockCheck • CyclomaticComplexityMethodCheck • EmptyRescueBodyCheck • MethodLineCountCheck • MethodNameCheck • ParameterNumberCheck • ...
  • 19. merb-action-args class Posts < Merb::Controller def create(post) # post = params[:post] @post = Post.new(post) @post.save end # ... end
  • 20. Heckle Think you write good tests? Not bloody likely... Put it to the test with heckle. It’ll put your code into submission in seconds.
  • 21. Outros • Reek (== roodi) • Flay • Rufus • ...
  • 22. Ambition User.select { |u| u.name == 'John' && u.age == 22 } # SELECT * FROM users WHERE users.name = 'John' AND users.age = 22 # quot;(&(name=jon)(age=21))quot;
  • 23. Ambition User.select { |u| u.name == 'John' && u.age == 22 } # SELECT * FROM users WHERE users.name = 'John' AND users.age = 22 # quot;(&(name=jon)(age=21))quot; User.select { |u| [1, 2, 3, 4].include? u.id } # SELECT * FROM users WHERE users.id IN (1,2,3,4)
  • 24. Ambition User.select { |u| u.name == 'John' && u.age == 22 } # SELECT * FROM users WHERE users.name = 'John' AND users.age = 22 # quot;(&(name=jon)(age=21))quot; User.select { |u| [1, 2, 3, 4].include? u.id } # SELECT * FROM users WHERE users.id IN (1,2,3,4) User.select { |u| u.friends.name =~ /bi/ } # SELECT * FROM users LEFT OUTER JOIN ... WHERE friends.name ~ 'bi'
  • 25. Ambition User.select { |u| u.name == 'John' && u.age == 22 } # SELECT * FROM users WHERE users.name = 'John' AND users.age = 22 # quot;(&(name=jon)(age=21))quot; User.select { |u| [1, 2, 3, 4].include? u.id } # SELECT * FROM users WHERE users.id IN (1,2,3,4) User.select { |u| u.friends.name =~ /bi/ } # SELECT * FROM users LEFT OUTER JOIN ... WHERE friends.name ~ 'bi' User.select { |u| ... }.sort_by { |u| u.name } # SELECT * FROM users WHERE ... ORDER BY users.name
  • 27. Rfactor $$$ class Banco def transfere(origem, destino, valor) s(:class, puts quot;iniciando transferenciaquot; :Banco, puts quot;por favor, aguarde...quot; nil, # ... s(:scope, end s(:block, s(:defn, def incrementa_juros(taxa) :transfere, # ... s(:args, :origem, :destino, :valor),end s(:scope, end s(:block, s(:call, nil, :puts, s(:arglist, s(:str, quot;iniciando transferenciaquot;))), s(:call, nil, :puts, s(:arglist, s(:str, quot;por favor, aguarde...quot;)))))), s(:defn, :incrementa_juros, s(:args, :taxa), s(:scope, s(:block, s(:nil)))))))
  • 28. Ruby2Ruby var bloco = function() { alert(quot;hey, I'm a functionquot;); } bloco.toString();
  • 29. Ruby2Ruby var bloco = function() { alert(quot;hey, I'm a functionquot;); } bloco.toString(); bloco = lambda do puts quot;hey, I'm a blockquot; end bloco.to_ruby # => quot;proc { puts(quot;hey, I'm a blockquot;) }quot;
  • 30. metaprogramação: como fica o código gerado?
  • 32. require 'mapreduce_enumerable' (1..100).to_a.dmap do |item| item * 2 end http://romeda.org/blog/2007/04/mapreduce-in-36-lines-of-ruby.html
  • 36.
  • 37. • rb2js: http://rb2js.rubyforge.org • red-js: http://wiki.github.com/jessesielaff/red
  • 40. Código Nativo (problema) • ruby_parser • Ripper (1.9) • JRuby ParseTree
  • 41. Dúvidas? Obrigado! fabio.kung@caelum.com.br http://fabiokung.com twitter: fabiokung

Notes de l'éditeur

  1. outlines errors
  2. mapreduce.rb