ruby metaprogramming - oscon 2008

98
Metaprograming in Ruby Brian Sam-Bodden

Upload: brian-sam-bodden

Post on 19-Jan-2015

718 views

Category:

Technology


1 download

DESCRIPTION

Learn about the art of writing code that writes code. In this session we will explore some of the metaprogramming techniques that make Ruby the ideal language for framework development. Metaprogramming techniques can greatly reduce the amount of code you write while clarifying the intend of your code. Learn how frameworks like Ruby on Rails and others exploit metaprogramming to infuse that special magic that only open dynamic languages can produce.

TRANSCRIPT

  • 1. Metaprogramingin RubyBrian Sam-Bodden

2. Whats this all about? Well learn... mainly about Rubys Meta-programming power about a language doesnt treat you like a moron what happens when dynamic meets object-oriented why Ruby is superb for building frameworks what happens when meta-programming ...meets someone with too much free-time 3. Ruby 4. Ruby Ideals:Programming should be fun!I believe people want to express themselves when theyprogram.They dont want to ght with the language.Programming languages must feel natural toprogrammers.MatzThe language should treat you like a responsible adult! 5. Ruby 6. Rubyis... 7. Rubyis...Object-Oriented 8. Rubyis...Object-OrientedGeneral Purpose 9. Rubyis...Object-Oriented InterpretedGeneral Purpose 10. Rubyis...Object-OrientedDynamic InterpretedGeneral Purpose 11. Rubyis...Object-OrientedDynamic InterpretedGeneral Purpose Garbage-collected 12. Rubyis...Object-OrientedReective Dynamic InterpretedGeneral Purpose Garbage-collected 13. Rubyis...Object-OrientedReective Dynamic InterpretedGeneral Purpose Multi-paradigm Garbage-collected 14. Rubyis...Object-OrientedReective Dynamic InterpretedGeneral Purpose Multi-paradigm Garbage-collectedElegant 15. Without Ruby there would beno RailsRubys meta-programing is the keyfeature that makes Rails magical 16. OpenClasses 17. Say we have an Array like: 18. Say we have an Array like:[1,2,3,4,5] 19. Say we have an Array like:[1,2,3,4,5]and we want to sum ofall of its elements 20. Lets try something like: 21. Lets try something like:[1,2,3,4,5].sum 22. Lets try something like:[1,2,3,4,5].sum 23. Lets try something like:[1,2,3,4,5].sumRats! Doesnt work in Ruby 24. Lets try something like:[1,2,3,4,5].sumRats! Doesnt work in Ruby yet! 25. Ruby classes are 26. Ruby classes are 27. Ruby classes areWe can teach the Array class a new behavior 28. Ruby classes areWe can teach the Array class a new behavior 29. Lets try again! 30. Lets try again! 31. Lets try again!All you need to do is load the lecontaining the enhancements 32. Code asDataBend at will your code should 33. When code can be manipulated as dataa whole world of possibilities opensIn Ruby you can evaluate thecontents of a string 34. Code that invokes code,that invokes code 35. Code that invokes code,that invokes code 36. Code that invokes code,that invokes codeThere you go, there you go 37. Ruby provides the eval family ofmethods for runtime execution ofcode stored in strings 38. Ruby provides the eval family ofmethods for runtime execution ofcode stored in strings 39. Ruby provides the eval family ofmethods for runtime execution ofcode stored in stringseval will evaluate any string 40. instance_eval can evaluate astring or a code block 41. instance_eval can evaluate astring or a code block 42. instance_eval can evaluate astring or a code blockin the context of the receiver 43. class_eval can evaluate a string or a code blockin the context of the class or module it is called on 44. class_eval can evaluate a string or a code blockin the context of the class or module it is called on 45. In Ruby we try to think about sending a message toan object rather than calling a method on an object 46. In Ruby we try to think about sending a message toan object rather than calling a method on an objectIn simple cases (above) syntactic sugar hides it,but we can use it in interesting ways... 47. Meta-programming 48. ...is about programs thatwrite programsMeta-programming...its a superb tool for buildingframeworks...its the key ingredient for buildingdomain-specic languages 49. Rubys is a great vehicle formeta-programming because it is:dynamic and reexiveopen and malleableclean syntaxcode is data, data is codeprogramming event model 50. ...uses meta-programming to bringthe language closer to the problem...is a collection of domain-speciclanguages (DSL) for building webapplicationsRuby on Rails 51. SingletonClass 52. In Ruby you can enhance aparticular instance of a classRuby uses a proxy class known asthe singleton classMeta-class:The singleton forClass objects 53. class_eval indirectly uses the meta-classadding a singleton method to the class 54. Rails relies heavily on Rubys abilityto dynamically enhance a class 55. Rails relies heavily on Rubys abilityto dynamically enhance a class 56. Shortcuts such as dene_methodexist to make life easier 57. Accessing the singleton meta-classexplicitly 58. Child classes get enhanced withclass methods 59. Inheritancethe Ruby Way 60. Many Ruby DSLs create classmethods on subclasses using themeta-class (singleton class) 61. Rails uses this technique in ActiveRecord 62. A module with a Base class 63. Methods get added to our classes withsimple declarationsGetting closer to a DSL! 64. Now our class has a new set of classmethods 65. Now our class has a new set of classmethods 66. AOPthe RubyWay 67. With alias_method you can wrapan existing method... 68. ...effectively intercepting any callsand injecting any desired behavior 69. ...effectively intercepting any callsand injecting any desired behavior 70. Meta-ProgrammingEvents 71. Ruby has a rich event modelassociated with static and dynamicchanges of the codeIncluded Hook 72. Method Missing 73. Ruby provides several hookmethods that can be used to createdcustom behaviorsmethod_missingmethod_addedmethod_removed 74. Rubys Markup Builder is anexample of what can be achievedwith method missing 75. Lets implement the greeter exampleusing method_missing 76. greeter using method_missing 77. greeter using method_missing 78. Trellis...or what happens when you have too much timein between consulting gigsand your friends no longer call you 79. I was bored...In the Ruby world Ive worked with Rails and Merb...thinking of web apps in terms of request & responsemeanwhile... in the Java world I was working withTapestry and Wicket...thinking about Pages, Components and Events 80. Started to hack to see what it would be to buildsomething like Tapestry/Wicket in Ruby...actually it all started as an learning exercise...but then I kept going...somehow I ended building component-orientedweb framework in Ruby...part of a conversation among friends about the needfor IoC and AOP frameworks for dynamic languages 81. You might beasking yourself,but why? 82. Why not? 83. My goals:Magic like Rails; less code more action Small like Camping... a micro-frameworkComponents like Tapestry/WicketClean HTML templates......but also programatic HTML generationNon-managed components, no pooling 84. The big picture:Trellis ApplicationPages Componentshashas{declares pages useddeclares a home pagedispatches request to pages} {denes a templateprovides event handlerspasses events to thecomponentsprovides reusable logicresponds to eventscan be stateless (tags)or stateful 85. The simplest Trellis App, one Application and one PageThe CodeThe Template 86. What did I use to put this thing together...A boat load of meta-programmingRack ...HTTP the Ruby wayRadius ...XML tags for the templatesBuilder ...for building HTML/XMLHpricot, REXML ...parsing searching HTML/XMLPaginator ...for duh, paginationParts of Rails ...so far ActiveSupport (Inectors) 87. Lets do some code spelunking on the Trellis codebase...yes, there are some things that Im not proud of but......this is pre-alpha, unreleased v0.000001;-) 88. Some of the example applications that Ive puttogether in order of complexityhiloguest_bookhangmanyuistateful_countersickrsimple_blogcrud_components 89. What havewe learned? 90. There is more to Ruby than Rails!Building a Framework?Give Ruby a try!Build the language up towardsthe problem 91. Rack: http://rack.rubyforge.orgRadius: http://radius.rubyforge.orgHpricot: http://code.whytheluckystiff.net/hpricotREXML: http://www.germane-software.com/software/rexmlBuilder: http://builder.rubyforge.orgPaginator: http://paginator.rubyforge.orgYUI (Yahoo! UI Library): http://open.yahoo.com/yuiTrellis (Not ReleasedYet)Trellis @ RubyForge: http://rubyforge.org/projects/trellisTrellis Website: http://www.trellisframework.orgResources 92. www.integrallis.com