Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

francesco agati
francesco agati

Posted on

DSL in Ruby with Metaprogramming

Metaprogramming in Ruby allows developers to write programs that can modify themselves at runtime. This powerful feature can be leveraged to create expressive and flexible domain-specific languages (DSLs).

Defining the Structure

First, let's define the core class of our DSL,TravelSearch, along with auxiliary classesAir,Hotel, andTrain. These classes will encapsulate the details of each travel component.

classTravelSearchattr_accessor:air,:hotel,:traindefinitialize(&block)instance_eval(&block)enddefair(&block)@air=Air.new(&block)enddefhotel(&block)@hotel=Hotel.new(&block)enddeftrain(&block)@train=Train.new(&block)enddefto_s"Air:#{@air}\nHotel:#{@hotel}\nTrain:#{@train}"endendclassAirattr_accessor:from,:to,:datedefinitialize(&block)instance_eval(&block)enddeffrom(from)@from=fromenddefto(to)@to=toenddefdate(date)@date=dateenddefto_s"from#{@from} to#{@to} on#{@date}"endendclassHotelattr_accessor:city,:date,:nightsdefinitialize(&block)instance_eval(&block)enddefcity(city)@city=cityenddefdate(date)@date=dateenddefnights(nights)@nights=nightsenddefto_s"in#{@city} on#{@date} for#{@nights} nights"endendclassTrainattr_accessor:from,:to,:via,:date,:with_seat_reservationdefinitialize(&block)instance_eval(&block)enddeffrom(from)@from=fromenddefto(to)@to=toenddefvia(via)@via=viaenddefdate(date)@date=dateenddefwith_seat_reservation(with_seat_reservation)@with_seat_reservation=with_seat_reservationenddefto_s"from#{@from} to#{@to} via#{@via} on#{@date} with seat reservation:#{@with_seat_reservation}"endend
Enter fullscreen modeExit fullscreen mode

Utilizinginstance_eval for DSL Construction

Theinstance_eval method is a key component in our DSL. It allows us to evaluate the given block within the context of the current object, effectively changing theself to the object the method is called on. This is crucial for making the DSL syntax intuitive and clean.

Creating the DSL Entry Point

We'll define a methodsearch_travel as the entry point for our DSL. This method initializes aTravelSearch object and evaluates the block within its context.

defsearch_travel(&block)travel_search=TravelSearch.new(&block)putstravel_searchend
Enter fullscreen modeExit fullscreen mode

Example Usage

Here's an example of how our DSL can be used to define a travel search:

search_traveldoairdofrom"SFO"to"JFK"date"2011-12-25"endhoteldocity"New York"date"2011-12-25"nights3endtraindofrom"Milan"to"Rome"via"Florence"date"2011-12-25"with_seat_reservationtrueendend
Enter fullscreen modeExit fullscreen mode

Output

Running the above code will produce the following output:

Air: from SFO to JFK on 2011-12-25Hotel: in New York on 2011-12-25 for 3 nightsTrain: from Milan to Rome via Florence on 2011-12-25 with seat reservation: true
Enter fullscreen modeExit fullscreen mode

Usinginstance_eval and metaprogramming, we created a flexible and readable DSL for travel searches in Ruby. This approach allows users to define complex data structures with minimal syntax, making the code more expressive and easier to understand.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

  • Joined

More fromfrancesco agati

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp