advanced dsls in ruby

78
NEAL FORD thoughtworker / meme wrangler ThoughtWorks 14 Wall St, Suite 2019, New York, NY 10005 [email protected] www.nealford.com www.thoughtworks.com memeagora.blogspot.com ThoughtWorks ThoughtWorks advanced dsl’s in ruby

Upload: dmytro-shteflyuk

Post on 12-Nov-2014

816 views

Category:

Documents


2 download

DESCRIPTION

Building Domain Specific Languages in Ruby shows the power and flexibility of the language.This talk covers some advanced DSL techniques in Ruby, including building really fluent interfaces, building natural language-styel DSLs, using sticky attributes, factories via const_missing, bubling methods, and other techniques. This session goes beyond the general syntactic tricks used to create DSLs; it shows how to make internal DSLs in Ruby a compelling abstraction mechanism for building frameworks and other tools.

TRANSCRIPT

Page 1: Advanced DSLs in Ruby

NEAL FORD thoughtworker / meme wrangler

ThoughtWorks14 Wall St, Suite 2019, New York, NY 10005 nford@thoughtworks.comwww.nealford.comwww.thoughtworks.commemeagora.blogspot.com

ThoughtWorksThoughtWorks

advanced dsl’s in ruby

Page 2: Advanced DSLs in Ruby

ThoughtWorks

Page 3: Advanced DSLs in Ruby

polishing, preprocessing, and parsing

context and why it’s important

building fluent interfaces

prototype-based dsl toolkits

business natural languages

what i cover:

Page 4: Advanced DSLs in Ruby

a word aboutpatterns

Page 5: Advanced DSLs in Ruby

Bakery

Page 6: Advanced DSLs in Ruby

...but the other guys do the same thing

competition is brutal!

incentives to encourage repeat customers...

easy to define & change

flexible business rules

bakery life

Page 7: Advanced DSLs in Ruby

establishing profiles

Page 8: Advanced DSLs in Ruby

method chainingMake modifier methods return the host object so that multiple modifiers can be invoked in a single

expression.

Page 9: Advanced DSLs in Ruby

discounts

Page 10: Advanced DSLs in Ruby
Page 11: Advanced DSLs in Ruby
Page 12: Advanced DSLs in Ruby
Page 13: Advanced DSLs in Ruby
Page 14: Advanced DSLs in Ruby

WTF?!?

Warning,Test Failed

Page 15: Advanced DSLs in Ruby

why did it fail?

Page 16: Advanced DSLs in Ruby

the finishing problem

Page 17: Advanced DSLs in Ruby
Page 18: Advanced DSLs in Ruby
Page 19: Advanced DSLs in Ruby

use method chaining for stateless object construction

Page 20: Advanced DSLs in Ruby

use nested methods to control completion

Page 21: Advanced DSLs in Ruby

recipes

Page 22: Advanced DSLs in Ruby

the goal

Page 23: Advanced DSLs in Ruby

open classes

Page 24: Advanced DSLs in Ruby

recipe redux

Page 25: Advanced DSLs in Ruby

of

Page 26: Advanced DSLs in Ruby

who returns what?

Integer

Numeric

Ingredient

Ingredient

Page 27: Advanced DSLs in Ruby

type transmogrification

transform types as needed as part of a fluent interface call

Page 28: Advanced DSLs in Ruby

killing noise characters

Page 29: Advanced DSLs in Ruby

const_missing

Page 30: Advanced DSLs in Ruby

constant_missing factory

using “missings” as factories to create types

Page 31: Advanced DSLs in Ruby

ingredient factoryyikes!

Page 32: Advanced DSLs in Ruby

mix it in

Page 33: Advanced DSLs in Ruby

safer const factories

Page 34: Advanced DSLs in Ruby

smarter const factories

Page 35: Advanced DSLs in Ruby
Page 36: Advanced DSLs in Ruby

shotgun approach to open classes

don’t provide universe-wide access to the whacky stuff you’ve implemented for your dsl

control your context

Page 37: Advanced DSLs in Ruby

context

Page 38: Advanced DSLs in Ruby

context

implicit context tersifies dsl’s

Page 39: Advanced DSLs in Ruby

context

Page 40: Advanced DSLs in Ruby

add context

evaluates ruby code by switching self to the instance of the object calling instance_eval

Page 41: Advanced DSLs in Ruby

context

Page 42: Advanced DSLs in Ruby

bubble methods &really fluent interfaces

Page 43: Advanced DSLs in Ruby

building a simple language for recipes allows you to build other stuff underneath

for example, a nutrition profile

expression builder

Page 44: Advanced DSLs in Ruby

recipe nutrition profile

Page 45: Advanced DSLs in Ruby

nutrition profile

Page 46: Advanced DSLs in Ruby

testing profile

Page 47: Advanced DSLs in Ruby

profile target

Page 48: Advanced DSLs in Ruby

what is this?method

1st parameter

“bubble” word

2nd parameter(s)

Page 49: Advanced DSLs in Ruby

bubble words

terms in a dsl that don’t contribute to the definition but rather to the

readability

Page 50: Advanced DSLs in Ruby
Page 51: Advanced DSLs in Ruby
Page 52: Advanced DSLs in Ruby
Page 53: Advanced DSLs in Ruby

warning! do not try to parse text using regular expressions!

Page 54: Advanced DSLs in Ruby

bad idea

Page 55: Advanced DSLs in Ruby
Page 56: Advanced DSLs in Ruby
Page 57: Advanced DSLs in Ruby
Page 58: Advanced DSLs in Ruby

polish vs.preprocess vs.

parse

Page 59: Advanced DSLs in Ruby

polish

simple string substitutions to

convert nearly ruby to actual ruby

Page 60: Advanced DSLs in Ruby

pre-process

load strings and modify to coerce

them into ruby code

Page 61: Advanced DSLs in Ruby

parse

parse strings (and files) into your own language

Page 62: Advanced DSLs in Ruby

bnl is a dsl, but not all dsl’s are bnl’s

term defined by jay fields (www.jayfields.com)

use natural language to represent business logic

business natural languages

Page 63: Advanced DSLs in Ruby

example

Page 64: Advanced DSLs in Ruby

process_payroll.rb

Page 65: Advanced DSLs in Ruby

vocabulary.rb

Page 66: Advanced DSLs in Ruby

compensation_vocabulary.rb

Page 67: Advanced DSLs in Ruby

compensation_parser.rb

Page 68: Advanced DSLs in Ruby
Page 69: Advanced DSLs in Ruby

prototype based language tools

Page 70: Advanced DSLs in Ruby

under the radar, but open source

created by matt deiters based on project work

prototype based dsl generator

git://github.com/mdeiters/semr.git

semr

Page 71: Advanced DSLs in Ruby

semr example

Page 72: Advanced DSLs in Ruby

language.rb

Page 73: Advanced DSLs in Ruby

language.rb

Page 74: Advanced DSLs in Ruby

...it generates a dsl processor for you

prototype style dsl processor

you give it a dsl (like bnl)...

git://github.com/olabini/xample.git

very much a work in progress (blame ioke)

Xample

Page 75: Advanced DSLs in Ruby

xamples

Page 76: Advanced DSLs in Ruby

english isn’t a particularly good target

implicit context is everything

don’t hack up the core language just to make a dsl

think hard about polish/preprocess/parse

tools are getting smarter

summary

Page 77: Advanced DSLs in Ruby

ThoughtWorks

NEAL FORD thoughtworker / meme wrangler

ThoughtWorks14 Wall St, Suite 2019, New York, NY 10005 nford@thoughtworks.comwww.nealford.comwww.thoughtworks.commemeagora.blogspot.com

This work is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 2.5 License.

http://creativecommons.org/licenses/by-nc-sa/2.5/

questions?

please fill out the session evaluationsslides & samples available at nealford.com

Page 78: Advanced DSLs in Ruby

resources

ThoughtWorks

Text

Text

Text

Text

Text