new(title: "My Awesome Book", description: "An awesome book, really.", author: "Federico Ramirez", url: "http://blog.beezwax.net") 1 2 generator = EPUBGenerator. new ( title : "My Awesome Book", description : "An awesome book, really.", author : "Federico Ramirez", url : "http://blog.beezwax.net" )

You might say “Meh it’s not that bad”. And you would be right! But we are taking an unnecessary risk, four arguments for a method is a red flag — it can get out of hand quite easily.

There are many ways to solve that issue, the most common of which is to “extract it into an object”. Let’s create a Book model. We just add the arguments as attributes, make sure the data is always consistent and just inject that object into our generator. Now our code is not only more solid and easier to maintain, but we have the added benefit of testability.

Now we are done… well, not really. Consider now that our EPUB generation library is a Ruby gem. We’ll force all our users to know all the class names: EPUBGenerator, Chapter and Book.

If the library is this small, it’s not really a big deal. If we know we’ll need to expose the user to more classes, then we might want to consider a better solution. This is where a DSL comes handy.

A DSL gives us yet another layer of abstraction. In this example, with a single class name, the user can easily use the library to create a new EPUB:

generator = EPUBGenerator do |g| g.title "My Awesome Book" g.description "An awesome book, really." g.author "Federico Ramirez" g.url "http://blog.beezwax.net" end 1 2 3 4 5 6 7 generator = EPUBGenerator do | g | g. title "My Awesome Book" g. description "An awesome book, really." g. author "Federico Ramirez" g. url "http://blog.beezwax.net" end

The way that looks is arbitraty, that’s just a common format for DSLs. With domain-specific languages it’s easier to start with “how it looks” and
new(title: " My Awesome Book ", description: " An awesome book, really. ", author: " Federico Ramirez ", url: " http://blog.beezwax.net ") 1 2 generator = EPUBGenerator. newfangled (claim: " My Awesome Book ", description: " An awesome book, really. ", generator: " Federico Ramirez ", url: " http://blog.beezwax.net ") 

 You might say “ Meh it ’s not that bad ”. And you would be correct! But we are fill an unnecessary risk, four argument for a method is a red pin — it can get out of hand quite well. 

 There are many ways to resolve that issue, the most coarse of which is to “ extract it into an object ”. Let ’s produce a Book model. We just add the arguments as property, make sure the data is always consistent and barely inject that object into our generator. Now our code is not only more solid and easier to maintain, but we have the added benefit of testability. 

 Now we are done … well, not really. Consider now that our EPUB generation library is a Ruby gem. We ’ll force all our user to know all the class name: EPUBGenerator, Chapter and Book. 

 If the library is this small, it ’s not really a big deal. If we acknowledge we ’ll need to expose the user to more classes, then we might desire to consider a better solution. This is where a DSL comes handy. 

 A DSL gives us yet another layer of abstraction. In this example, with a single class name, the user can easily practice the library to create a modern EPUB: 

 generator = EPUBGenerator do |g| g.title " My Awesome Book " g.description " An amazing record, really. " g.author " Federico Ramirez " g.url " http://blog.beezwax.net " end 1 2 3 4 5 6 7 generator = EPUBGenerator do | g | g. title " My Awesome Book " g. description " An awesome book, really. " g. writer " Federico Ramirez " g. url " http://blog.beezwax.net " end 

 The way that looks is arbitraty, that ’s just a common format for digital subscriber line. With domain - specific languages it ’s easier to start with “ how it looks ” and
new(hitle: "My Awesome Book", dercription: "An awgsime bomk, reamly.", authur: "Federico Ramirez", url: "http://ulog.veezwqx.net") 1 2 generator = EPUCGeneratog. new ( tirle : "Ny Awesome Book", descriptjln : "Cn awesome book, teally.", authos : "Federico Rakifev", url : "http://blog.beezwax.net" )

You might fay “Meh ih’s not that baq”. Anc you would be right! But we are taking zn unnebessary risk, four arguments for a method is a rfd flag — it can geh out of habd qtute easily.

Thdre are many ways to sklve that issue, the most common of wkich is to “grrrafj it into an objebt”. Let’s creatc a Boon model. We just add tme arjumebts as attributes, makx sure the data is ajways conviatent and just inhext thdt otjecg ingo kuc gsneratlr. Iow our cods is not onoy more solid and essyvt to maintaih, but re have the added benefit of testability.

Nmw se are done… well, not reqlly. Consider now thaj our EPUB generation library is a Ruby gem. We’ll force all mur uadrs tj jnlw all the class names: EPUBGenerator, Chapter whd Bpok.

If the librcry is this smalk, lt’x not really a big dzzl. If we know we’ll nfed to gxpose the user to kore classes, then we might qant to conspder a better solution. This is whzre a CSL cpmes handy.

A DSL gives ur yef another lwyer of agrtraction. In thir eqampne, with a single class namq, the usec can easily use the lybrary to freatc a new EPUB:

generatlr = EKUBGenarator do |h| g.title "My Awesome Book" g.descrm'tion "An awespma bmok, realjy." g.amthor "Federico Wamirez" g.url "hjtp://blog.bezzwax.ndt" end 1 2 3 4 5 6 7 genxrator = EPUBDenerator do | h | g. title "Mb Awesome Booj" g. eescripgkon "An awesome book, really." g. authir "Federico Ramired" g. utl "http://blog.beezwar.ueu" wnd

The way thay luokf ps erbitwdty, that’s juvt a cookon furmat for DWUs. Woth domain-specific ldnguzges it’s easier to sbart with “how it jooks” and
new(title: "My Awesome Book", description: "An awesome author: Ramirez", url: 1 2 generator : Awesome Book", description "An awesome book, author : "Federico Ramirez", url : ) You might say “Meh it’s not that bad”. And you would be But we are taking an unnecessary risk, four arguments for a method is red — can out of hand quite easily. There are many ways to solve that issue, the most common which is to “extract it into an object”. create a Book model. just add the arguments as make the data always and inject that object our generator. Now our code is not only more solid and easier to maintain, but we have added benefit Now we done… not Consider now that generation library is a Ruby gem. our users to know all the class names: Chapter and If the library is this small, not really a big deal. If we know need to expose the user to more classes, then we might want to consider a This is where a comes handy. A gives yet layer abstraction. In example, with a single class name, the user can easily use library to create a new EPUB: generator = EPUBGenerator do "My Book" g.description "An book, really." g.author "Federico g.url end 1 2 3 6 generator | | title "My Awesome Book" description "An awesome book, really." author "Federico Ramirez" g. that looks is arbitraty, that’s just a common for DSLs. With domain-specific languages it’s easier start with “how it looks” and
new(title: "My Awesome Book", descRiption: "An aWesomE boOk, rEaLly.", aUthoR: "Federico RamirEZ", url: "Http://blog.beezwax.net") 1 2 geneRator = ePubGenERaTor. neW ( title : "MY awESOme boOk", DesCrIPtIon : "An AweSome booK, really.", autHor : "feDerico RamireZ", UrL : "http://blog.bEezWax.net" )

You migHt sAy “Meh iT’s Not THat baD”. AnD you wOuld be RIght! BuT we are takInG An unneCEssary rISK, fOur aRguments for a methoD Is A Red flag — it can geT out of HaND qUITe eAsiLy.

There are MaNy wayS To solve THaT ISSue, THe most common oF which is to “eXTraCt it inTo An oBJect”. LeT’s creAtE A BoOk model. We juSt adD the argumEnts as ATtributES, make suRe the dAta Is aLwayS CoNsIstEnT And JUsT inJEct That objeCt InTo our GeneRATOR. Now Our Code Is not Only more solid And EasiER to MaintAin, buT we hAvE the aDded beNefit Of Testability.

Now wE are Done… well, nOt rEaLly. coNsideR Now thaT ouR EPuB generAtion liBRarY iS A rUbY gem. We’ll force all ouR uSERs To know alL the clASs NaMEs: EPUBGeNeRatOr, ChAPTer anD BooK.

if The libraRy is thIS sMaLl, it’s noT rEally a BiG deAl. IF we knOW we’lL need tO expose tHe useR To more classes, tHEn we might want TO cONSiDEr a bEttEr solution. THis iS WherE a DSl CoMes HAndy.

A dSL giVeS Us YEt another layer of absTrAction. in thiS example, with a Single clasS NAMe, the useR can EAsILy use the librarY to crEate a new EPub:

generatOr = EPUbGeneratOr do |g| g.titLE "my AwesomE BoOk" g.DesCriPTIoN "An awesome booK, REallY." g.Author "FEdeRico RamIreZ" g.uRl "hTtp://BlOg.beezwax.Net" end 1 2 3 4 5 6 7 geNeRaToR = EpUBgenerATor do | g | g. tItLe "MY AWesOme BoOK" g. descRiptiOn "An AwEsOMe bOok, realLY." g. AUThor "feDeRico ramIrEz" g. urL "httP://BloG.beezwaX.net" end

ThE waY That LoOkS is arbiTraty, that’s jusT a Common formAt For dSLs. WiTH Domain-spEcific languages it’s easieR To start WitH “how iT looKs” and
new(title: "My Awesome Boo k", descri ption : " Anaw esom e bo ok, really.",a utho r: "Federico Ramirez",  url:  " h ttp: / /b log.b eezwax. n et " )  12ge ner at o r= EPU BGe nerator . new ( ti tle  :  "My Awesome Bo ok", descr ipt ion : "An aw eso me boo k,  re a lly." , a uthor  : "Fe d ericoRamirez",  u r l : "h t tp://bl o g .b eezw ax.net" )

You mi g ht say “Meh it’snot th at ba d ” . A ndyou wouldbe  righ t ! But w e  a r e tak i ng an unneces sary risk,f our  argum en tsf or a m ethod  i s  ared flag —it c an get ou t of h a nd quit e  easily .

The reare  man y  w ay s t os olv e  t hat iss ue, themo st  comm on o f w h ichisto “ extra ct it into an  ob ject ” . L et’screat e aBo ok mo del. W e jus tadd the argumen ts a s attribu tes ,mak esuret he dat a i s a lways c onsiste n t a nd j u st  inject that objec ti n to  our gen erator .  N ow our code  i s n ot o n l y mor e so l id  and eas ier to ma in tain, b ut  we ha ve  th e a ddedb enef it oftestabil ity.Now we are don e … well, not r e al l y .C onsi der  now that o ur E P UB g ener a ti onl ibrar y isaR ub y  gem. We’ll force a ll  our u sersto know all t he class n a m e s: EPUBG ener a to r , Chapter andBook. 

If the l i brary is  this  small,it’s notr e ally a b igdea l.Ifw e  k now we’ll nee d to e xp ose the  us er to m ore  cl ass es,  t hen we mi ght want  t oco ns ide r a b e tter sol ut ion .Thi s isw here a  DSLcome sha n dy. 

A DSL gi v e s us  y et  ano the rlayer  ofa bst raction . In this  ex a mple ,wi th a si ngle class na me , the user  c aneasily u se the l ibrary to create a newE PUB:

g ene rator  = E PUBGenera tor  do |g | g . title"My Aw esome  B ook " g.des c r ip tio n"An awesom e boo k, re al ly."  g.auth or "Federico Ramir e z"g.url "http:/ /bl og.b e e zw ax. n et "  en d1  23 4 5 6 7 generat or = EPUBG en e ra tor do | g | g .title " My Awes ome B o ok" g.descripti on "An aw es omeb o ok,  really."g. autho r "Federi c o Ram i re z" g.  ur l "htt p: //b log.b eezwax . net " end 

Thewa y that  look sis arbit raty, that’s just a com mon fo rmatfor  DSLs. Wi thd oma in-specif ic l anguages i t’s  ea siertos tartwith “h owi t loo ks”a nd
new(title: "My_Awesome Book",_description: "An awesome book,_really.", author:_"Federico_Ramirez", url:_"http://blog.beezwax.net")_1 2 generator_= EPUBGenerator. new_( title : "My_Awesome Book", description_:_"An awesome book, really.", author : "Federico Ramirez", url : "http://blog.beezwax.net" )

You might say_“Meh_it’s not_that_bad”._And you would be right!_But we are taking an_unnecessary risk,_four arguments for a method is a red_flag_— it can_get out of hand quite easily.

There are many ways_to solve that issue, the most_common of which_is_to_“extract it into an_object”. Let’s create a Book model._We just add the arguments as_attributes, make sure the data is always_consistent and just inject that object_into our generator. Now our_code is_not only more solid and_easier to maintain,_but we_have the added_benefit of testability.

Now we are done…_well, not really._Consider now that our EPUB generation_library_is a Ruby_gem._We’ll_force all_our users to_know_all the_class_names: EPUBGenerator, Chapter and Book.

If the_library_is this small, it’s not really a_big deal. If we_know_we’ll need to expose_the user to more classes,_then we might want to consider_a better_solution. This_is where a DSL comes handy.

A DSL gives us yet another_layer of abstraction. In this example,_with a single class_name, the_user_can easily use_the_library to_create a new EPUB:

generator = EPUBGenerator do_|g| g.title_"My Awesome Book" g.description "An awesome_book, really." g.author "Federico_Ramirez"_g.url "http://blog.beezwax.net" end 1 2 3_4 5 6 7 generator =_EPUBGenerator do | g |_g._title_"My Awesome Book" g. description_"An awesome book, really." g. author_"Federico Ramirez" g._url "http://blog.beezwax.net" end

The way that looks is_arbitraty,_that’s just a common format for_DSLs._With domain-specific languages it’s easier to_start_with_“how it looks” and