The Basis of Making DSL with Ruby
Upcoming SlideShare
Loading in...5
×
 

The Basis of Making DSL with Ruby

on

  • 4,320 views

Slides of my talk in RubyKaigi 2010 on DSLs.

Slides of my talk in RubyKaigi 2010 on DSLs.

Statistics

Views

Total Views
4,320
Views on SlideShare
4,227
Embed Views
93

Actions

Likes
10
Downloads
61
Comments
1

4 Embeds 93

http://blazingcloud.net 81
http://blog.blazingcloud.net 6
http://us-w1.rockmelt.com 4
https://twitter.com 2

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • sorry, config/initializer should be config/initializers in P84
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

The Basis of Making DSL with Ruby The Basis of Making DSL with Ruby Presentation Transcript

  • The Basis of Making DSL with Ruby 2010 8 28
  • Who I am • Yasuko Ohba • Ruby Programmer • Developing rails applications and iPhone applications • Everyleaf Corporation 2010 8 28
  • Housekeeping Book on Web Kozuchi • http://www.kozuchi.net • http://github.com/everyleaf/kozuchi 2010 8 28 View slide
  • • @nay3 (twitter) • http://github.com/nay • y.ohba@everyleaf.com 2010 8 28 View slide
  • 2010 8 28
  • 2010 8 28
  • 2010 8 28
  • 2010 8 28
  • 2010 8 28
  • 2010 8 28
  • 2010 8 28
  • Ruby is good for DSL 2010 8 28
  • Domain Specific Language 2010 8 28
  • DSL 2010 8 28
  • DSL Hospitals 2010 8 28
  • Libraries DSL Hospitals 2010 8 28
  • Libraries Game DSL Hospitals 2010 8 28
  • Libraries Game DSL Hospitals EC 2010 8 28
  • It looks like a language rather than a program 2010 8 28
  • DSL 2010 8 28
  • internal DSL 2010 8 28
  • external internal DSL 2010 8 28
  • internal DSL in Ruby 2010 8 28
  • DSL examples • Rails • routes.rb • migrations • RJS • RSpec • Rake 2010 8 28
  • DSL-like codes : Rails class NotesController before_filter :find_group ... end 2010 8 28
  • before_filter :find_group 2010 8 28
  • It doesn’t look like DSL ? 2010 8 28
  • it can be less DSL like self.add_before_filter_methods( :find_group) 2010 8 28
  • much more DSL like self.add_before_filter_methods( :find_group) before_filter :find_group 2010 8 28
  • My talk is simple 2010 8 28
  • I’ll talk about readable codes 2010 8 28
  • DSL-like codes : migrations create_table :users do |t| t.string :name t.timestamps end 2010 8 28
  • DSL-like codes : RSpec describe Group do it “name ” do g = Group.new g.should_not be_valid end 2010 8 28
  • Easy to read 2010 8 28
  • Easy to write 2010 8 28
  • Brief 2010 8 28
  • Easy to maintain 2010 8 28
  • OK, but... 2010 8 28
  • Do we just use existing great DSLs ? Photo by Lawrence OP 2010 8 28
  • NO 2010 8 28
  • Write your ruby codes like DSL everyday 2010 8 28
  • That’s just a skill of programming in Ruby 2010 8 28
  • I’m going to talk about 2010 8 28
  • ..how to make your codes like DSL 2010 8 28
  • Our goal 2010 8 28
  • DSL-likeness 2010 8 28
  • What decides whether it is DSL or not ? 2010 8 28
  • No Solid Boundary 2010 8 28
  • But we can feel it 2010 8 28
  • to make the difference clear 2010 8 28
  • Compare normal Ruby codes and DSLs 2010 8 28
  • Normal Ruby Style “Hey receiver, do/return THIS !” 2010 8 28
  • Hey receiver do THIS! array.clear array[1] array.collect!{...} hash.delete(key) string.empty? 2010 8 28
  • Because it’s OOP 2010 8 28
  • DSLs have another styles 2010 8 28
  • 3 typical forms 2010 8 28
  • 1.Declarative Programming 2.Using Blocks 3.Methods Represent Special Concepts 2010 8 28
  • 1. Declarative Programming 2010 8 28
  • “I am a rubyist” 2010 8 28
  • examples : declarative expression validates_presence_of :name before_filter ... has_many :children 2010 8 28
  • typical features • describe status or nature • receivers are not always important • no brackets 2010 8 28
  • No money self.money = 0 2010 8 28
  • No money self.money = 0 poor 2010 8 28
  • Mostly in Class Definitions 2010 8 28
  • No money class Boy poor ... end 2010 8 28
  • Try to express your request as a nature of the class 2010 8 28
  • Object task task task 2010 8 28
  • the class has this nature Object task task task 2010 8 28
  • Modules are good to express natures Class Object 2010 8 28
  • Modules are good to express natures Class Object Module 2010 8 28
  • Modules are good to express natures Class Object Module Module 2010 8 28
  • implementation 2010 8 28
  • Example 1 Declare the class to have some nature implemented as a module 2010 8 28
  • Book (Class) class Book include "Product" ... end Product 2010 8 28
  • class Book include "Product" ... end class Book acts_as_product ... end 2010 8 28
  • class Book acts_as_product ... end NameError: undefined local variable or method `acts_as_product' for Book:Class 2010 8 28
  • You need acts_as_product method 2010 8 28
  • in the super class 2010 8 28
  • Book Object (Class) (Class) acts_as_product 2010 8 28
  • Book Object (Class) (Class) acts_as_product 2010 8 28
  • Book Object (Class) (Class) acts_as_product Product 2010 8 28
  • the easier way class Object def self.acts_as_product include Product end end the caller (Book) will be self here 2010 8 28
  • Book (Class) class Book acts_as_product ... end Product 2010 8 28
  • 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
  • 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
  • Object (Class) ActsAsProduct 2010 8 28
  • Object (Class) add ActsAsProduct acts_as_product ClassMethods 2010 8 28
  • Book Object (Class) (Class) add ActsAsProduct acts_as_product ClassMethods 2010 8 28
  • Book Object (Class) (Class) call acts_as_product add ActsAsProduct acts_as_product ClassMethods 2010 8 28
  • Book Object (Class) (Class) call acts_as_product add ActsAsProduct acts_as_product Product ClassMethods 2010 8 28
  • Example 2 set @title for a layout in some actions in Rails controllers 2010 8 28
  • Request Controller index show new edit @title layout 2010 8 28
  • want to write like this class BooksController < ApplicationController title " ", :only => [:edit, :update] .... end 2010 8 28
  • Same Strategy 2010 8 28
  • add a class method in the super class 2010 8 28
  • ApplicationController title BooksController 2010 8 28
  • ApplicationController class ApplicationController < ... def self.title ... end end 2010 8 28
  • title " ", :only => [:edit, :update] 2010 8 28
  • ApplicationController class ApplicationController < ... attr_accessor :title def self.title(name, options={}) before_filter(options) {|controller| controller.title = name} end ..... 2010 8 28
  • English naming problems validate ? validates ? 2010 8 28
  • 2. Using Blocks 2010 8 28
  • examples : rake namespace :myapp do task :my_rake_task do # rake end end 2010 8 28
  • Example : Rails Form Helper form_for :book do |f| f.text_field :name f.submit end 2010 8 28
  • Usages of block for DSL • describe complex structure • get some tasks into a scope 2010 8 28
  • describe structure 2010 8 28
  • Example 3 Write a game rule using playing cards 2010 8 28
  • Sevens game 'sevens' do |g| g.use 53 g.deal 53, :to => :each_player ... end 2010 8 28
  • Top You Level Game game use deal 2010 8 28
  • class Game def use (card_size, options ={}) ... end def deal (card_size, options ={}) ... end end 2010 8 28
  • def game g = Game.new yield g end 2010 8 28
  • Top Game You Level 2010 8 28
  • Top Game You Level game Block 2010 8 28
  • Top Game You Level game new Block 2010 8 28
  • Top Game You Level game new Block 2010 8 28
  • Top Game You Level use game new deal Block 2010 8 28
  • want the block parameter removed? 2010 8 28
  • without parameter g game 'sevens' do use 53 deal 53, :to => :each_player ... end 2010 8 28
  • use instance_exec def game(&block) g = Game.new g.instance_exec(&block) end 2010 8 28
  • can be changed slightly game 'sevens' do uses 53 deals 53, :to => :each_player ... end 2010 8 28
  • 3. methods represent special concepts 2010 8 28
  • methods that work as noun 2010 8 28
  • methods that represent vocabularies in another language 2010 8 28
  • books_url f.submit page.assert session request current_user 2010 8 28
  • an extra DSL style 2010 8 28
  • 4. Methods to make codes like English 2010 8 28
  • should it years_since bytes from_now 2010 8 28
  • Balance REALLY Cosmos Useful ? of OOP 2010 8 28
  • General Tips 2010 8 28
  • General Tips • provide default values for parameters • use a hash parameter • use symbols • naming methods nicely 2010 8 28
  • Summary 2010 8 28
  • DSL is not very special 2010 8 28
  • Implementation will improve with DSL ideas 2010 8 28
  • Have a try ! 2010 8 28
  • The best way to learn is reading codes 2010 8 28
  • Thank you ! 2010 8 28