The Basis of Making DSL with Ruby

4,351 views
4,218 views

Published on

Slides of my talk in RubyKaigi 2010 on DSLs.

Published in: Technology
1 Comment
13 Likes
Statistics
Notes
  • sorry, config/initializer should be config/initializers in P84
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
4,351
On SlideShare
0
From Embeds
0
Number of Embeds
109
Actions
Shares
0
Downloads
66
Comments
1
Likes
13
Embeds 0
No embeds

No notes for slide

The Basis of Making DSL with Ruby

  1. 1. The Basis of Making DSL with Ruby 2010 8 28
  2. 2. Who I am • Yasuko Ohba • Ruby Programmer • Developing rails applications and iPhone applications • Everyleaf Corporation 2010 8 28
  3. 3. Housekeeping Book on Web Kozuchi • http://www.kozuchi.net • http://github.com/everyleaf/kozuchi 2010 8 28
  4. 4. • @nay3 (twitter) • http://github.com/nay • y.ohba@everyleaf.com 2010 8 28
  5. 5. 2010 8 28
  6. 6. 2010 8 28
  7. 7. 2010 8 28
  8. 8. 2010 8 28
  9. 9. 2010 8 28
  10. 10. 2010 8 28
  11. 11. 2010 8 28
  12. 12. Ruby is good for DSL 2010 8 28
  13. 13. Domain Specific Language 2010 8 28
  14. 14. DSL 2010 8 28
  15. 15. DSL Hospitals 2010 8 28
  16. 16. Libraries DSL Hospitals 2010 8 28
  17. 17. Libraries Game DSL Hospitals 2010 8 28
  18. 18. Libraries Game DSL Hospitals EC 2010 8 28
  19. 19. It looks like a language rather than a program 2010 8 28
  20. 20. DSL 2010 8 28
  21. 21. internal DSL 2010 8 28
  22. 22. external internal DSL 2010 8 28
  23. 23. internal DSL in Ruby 2010 8 28
  24. 24. DSL examples • Rails • routes.rb • migrations • RJS • RSpec • Rake 2010 8 28
  25. 25. DSL-like codes : Rails class NotesController before_filter :find_group ... end 2010 8 28
  26. 26. before_filter :find_group 2010 8 28
  27. 27. It doesn’t look like DSL ? 2010 8 28
  28. 28. it can be less DSL like self.add_before_filter_methods( :find_group) 2010 8 28
  29. 29. much more DSL like self.add_before_filter_methods( :find_group) before_filter :find_group 2010 8 28
  30. 30. My talk is simple 2010 8 28
  31. 31. I’ll talk about readable codes 2010 8 28
  32. 32. DSL-like codes : migrations create_table :users do |t| t.string :name t.timestamps end 2010 8 28
  33. 33. DSL-like codes : RSpec describe Group do it “name ” do g = Group.new g.should_not be_valid end 2010 8 28
  34. 34. Easy to read 2010 8 28
  35. 35. Easy to write 2010 8 28
  36. 36. Brief 2010 8 28
  37. 37. Easy to maintain 2010 8 28
  38. 38. OK, but... 2010 8 28
  39. 39. Do we just use existing great DSLs ? Photo by Lawrence OP 2010 8 28
  40. 40. NO 2010 8 28
  41. 41. Write your ruby codes like DSL everyday 2010 8 28
  42. 42. That’s just a skill of programming in Ruby 2010 8 28
  43. 43. I’m going to talk about 2010 8 28
  44. 44. ..how to make your codes like DSL 2010 8 28
  45. 45. Our goal 2010 8 28
  46. 46. DSL-likeness 2010 8 28
  47. 47. What decides whether it is DSL or not ? 2010 8 28
  48. 48. No Solid Boundary 2010 8 28
  49. 49. But we can feel it 2010 8 28
  50. 50. to make the difference clear 2010 8 28
  51. 51. Compare normal Ruby codes and DSLs 2010 8 28
  52. 52. Normal Ruby Style “Hey receiver, do/return THIS !” 2010 8 28
  53. 53. Hey receiver do THIS! array.clear array[1] array.collect!{...} hash.delete(key) string.empty? 2010 8 28
  54. 54. Because it’s OOP 2010 8 28
  55. 55. DSLs have another styles 2010 8 28
  56. 56. 3 typical forms 2010 8 28
  57. 57. 1.Declarative Programming 2.Using Blocks 3.Methods Represent Special Concepts 2010 8 28
  58. 58. 1. Declarative Programming 2010 8 28
  59. 59. “I am a rubyist” 2010 8 28
  60. 60. examples : declarative expression validates_presence_of :name before_filter ... has_many :children 2010 8 28
  61. 61. typical features • describe status or nature • receivers are not always important • no brackets 2010 8 28
  62. 62. No money self.money = 0 2010 8 28
  63. 63. No money self.money = 0 poor 2010 8 28
  64. 64. Mostly in Class Definitions 2010 8 28
  65. 65. No money class Boy poor ... end 2010 8 28
  66. 66. Try to express your request as a nature of the class 2010 8 28
  67. 67. Object task task task 2010 8 28
  68. 68. the class has this nature Object task task task 2010 8 28
  69. 69. Modules are good to express natures Class Object 2010 8 28
  70. 70. Modules are good to express natures Class Object Module 2010 8 28
  71. 71. Modules are good to express natures Class Object Module Module 2010 8 28
  72. 72. implementation 2010 8 28
  73. 73. Example 1 Declare the class to have some nature implemented as a module 2010 8 28
  74. 74. Book (Class) class Book include "Product" ... end Product 2010 8 28
  75. 75. class Book include "Product" ... end class Book acts_as_product ... end 2010 8 28
  76. 76. class Book acts_as_product ... end NameError: undefined local variable or method `acts_as_product' for Book:Class 2010 8 28
  77. 77. You need acts_as_product method 2010 8 28
  78. 78. in the super class 2010 8 28
  79. 79. Book Object (Class) (Class) acts_as_product 2010 8 28
  80. 80. Book Object (Class) (Class) acts_as_product 2010 8 28
  81. 81. Book Object (Class) (Class) acts_as_product Product 2010 8 28
  82. 82. the easier way class Object def self.acts_as_product include Product end end the caller (Book) will be self here 2010 8 28
  83. 83. Book (Class) class Book acts_as_product ... end Product 2010 8 28
  84. 84. class Object def self.acts_as_product include Product end end Execute this before acts_as_product is invoked Rails config/initializer/acts_as_product.rb 2010 8 28
  85. 85. the softer way module ActsAsProduct module ClassMethods def acts_as_product include Product end end def self.included(base) base.extend(ClassMethods) end end Object.instance_eval { include ActsAsProduct } 2010 8 28
  86. 86. Object (Class) ActsAsProduct 2010 8 28
  87. 87. Object (Class) add ActsAsProduct acts_as_product ClassMethods 2010 8 28
  88. 88. Book Object (Class) (Class) add ActsAsProduct acts_as_product ClassMethods 2010 8 28
  89. 89. Book Object (Class) (Class) call acts_as_product add ActsAsProduct acts_as_product ClassMethods 2010 8 28
  90. 90. Book Object (Class) (Class) call acts_as_product add ActsAsProduct acts_as_product Product ClassMethods 2010 8 28
  91. 91. Example 2 set @title for a layout in some actions in Rails controllers 2010 8 28
  92. 92. Request Controller index show new edit @title layout 2010 8 28
  93. 93. want to write like this class BooksController < ApplicationController title " ", :only => [:edit, :update] .... end 2010 8 28
  94. 94. Same Strategy 2010 8 28
  95. 95. add a class method in the super class 2010 8 28
  96. 96. ApplicationController title BooksController 2010 8 28
  97. 97. ApplicationController class ApplicationController < ... def self.title ... end end 2010 8 28
  98. 98. title " ", :only => [:edit, :update] 2010 8 28
  99. 99. ApplicationController class ApplicationController < ... attr_accessor :title def self.title(name, options={}) before_filter(options) {|controller| controller.title = name} end ..... 2010 8 28
  100. 100. English naming problems validate ? validates ? 2010 8 28
  101. 101. 2. Using Blocks 2010 8 28
  102. 102. examples : rake namespace :myapp do task :my_rake_task do # rake end end 2010 8 28
  103. 103. Example : Rails Form Helper form_for :book do |f| f.text_field :name f.submit end 2010 8 28
  104. 104. Usages of block for DSL • describe complex structure • get some tasks into a scope 2010 8 28
  105. 105. describe structure 2010 8 28
  106. 106. Example 3 Write a game rule using playing cards 2010 8 28
  107. 107. Sevens game 'sevens' do |g| g.use 53 g.deal 53, :to => :each_player ... end 2010 8 28
  108. 108. Top You Level Game game use deal 2010 8 28
  109. 109. class Game def use (card_size, options ={}) ... end def deal (card_size, options ={}) ... end end 2010 8 28
  110. 110. def game g = Game.new yield g end 2010 8 28
  111. 111. Top Game You Level 2010 8 28
  112. 112. Top Game You Level game Block 2010 8 28
  113. 113. Top Game You Level game new Block 2010 8 28
  114. 114. Top Game You Level game new Block 2010 8 28
  115. 115. Top Game You Level use game new deal Block 2010 8 28
  116. 116. want the block parameter removed? 2010 8 28
  117. 117. without parameter g game 'sevens' do use 53 deal 53, :to => :each_player ... end 2010 8 28
  118. 118. use instance_exec def game(&block) g = Game.new g.instance_exec(&block) end 2010 8 28
  119. 119. can be changed slightly game 'sevens' do uses 53 deals 53, :to => :each_player ... end 2010 8 28
  120. 120. 3. methods represent special concepts 2010 8 28
  121. 121. methods that work as noun 2010 8 28
  122. 122. methods that represent vocabularies in another language 2010 8 28
  123. 123. books_url f.submit page.assert session request current_user 2010 8 28
  124. 124. an extra DSL style 2010 8 28
  125. 125. 4. Methods to make codes like English 2010 8 28
  126. 126. should it years_since bytes from_now 2010 8 28
  127. 127. Balance REALLY Cosmos Useful ? of OOP 2010 8 28
  128. 128. General Tips 2010 8 28
  129. 129. General Tips • provide default values for parameters • use a hash parameter • use symbols • naming methods nicely 2010 8 28
  130. 130. Summary 2010 8 28
  131. 131. DSL is not very special 2010 8 28
  132. 132. Implementation will improve with DSL ideas 2010 8 28
  133. 133. Have a try ! 2010 8 28
  134. 134. The best way to learn is reading codes 2010 8 28
  135. 135. Thank you ! 2010 8 28

×