Your SlideShare is downloading. ×
Ruby, muito mais que reflexivo
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Ruby, muito mais que reflexivo

1,232
views

Published on

ParseTree permite formas bastante avançadas de reflexão sobre código Ruby. …

ParseTree permite formas bastante avançadas de reflexão sobre código Ruby.
Com seu uso, podemos até mudar completamente a forma como o código Ruby é interpretado!

A palestra passa por alguns usos divertidos e interessantes, desde análise estática de
código, até técnicas para construção de Domain Specific Languages.

Published in: Technology, Education

0 Comments
10 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,232
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
39
Comments
0
Likes
10
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide




















  • outlines
    errors






























  • mapreduce.rb


















  • Transcript

    • 1. Ruby muito mais do que reflexivo! fabio.kung@caelum.com.br
    • 2. 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;]
    • 3. Dinamismo
    • 4. Metaprogramação
    • 5. 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;
    • 6. “Skilled programmers can write better programmers than they can hire” -- Giles Bowkett
    • 7. Code as Data
    • 8. 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)
    • 9. 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”
    • 10. 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;))))))))
    • 11. Feedback Editores/IDEs
    • 12. 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, ...))))
    • 13. 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
    • 14. 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
    • 15. 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
    • 16. 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
    • 17. roodi Ruby Object Oriented Design Inferometer • ClassLineCountCheck • ClassNameCheck • CyclomaticComplexityBlockCheck • CyclomaticComplexityMethodCheck • EmptyRescueBodyCheck • MethodLineCountCheck • MethodNameCheck • ParameterNumberCheck • ...
    • 18. merb-action-args class Posts < Merb::Controller def create(post) # post = params[:post] @post = Post.new(post) @post.save end # ... end
    • 19. 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.
    • 20. Outros • Reek (== roodi) • Flay • Rufus • ...
    • 21. 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;
    • 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; User.select { |u| [1, 2, 3, 4].include? u.id } # SELECT * FROM users WHERE users.id IN (1,2,3,4)
    • 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) User.select { |u| u.friends.name =~ /bi/ } # SELECT * FROM users LEFT OUTER JOIN ... WHERE friends.name ~ 'bi'
    • 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' User.select { |u| ... }.sort_by { |u| u.name } # SELECT * FROM users WHERE ... ORDER BY users.name
    • 25. ParseTree Manipulation http://martinfowler.com/dslwip/ParseTreeManipulation.html
    • 26. 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)))))))
    • 27. Ruby2Ruby var bloco = function() { alert(quot;hey, I'm a functionquot;); } bloco.toString();
    • 28. 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;
    • 29. metaprogramação: como fica o código gerado?
    • 30. serialização de código
    • 31. 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
    • 32. Ofuscação
    • 33. Ruby2Java
    • 34. Ruby2Java
    • 35. • rb2js: http://rb2js.rubyforge.org • red-js: http://wiki.github.com/jessesielaff/red
    • 36. JRuby compiler2.rb
    • 37. Geradores • Gráficos • UML • ...
    • 38. Código Nativo (problema) • ruby_parser • Ripper (1.9) • JRuby ParseTree
    • 39. Dúvidas? Obrigado! fabio.kung@caelum.com.br http://fabiokung.com twitter: fabiokung

    ×