The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
More on Business DSLs in Ruby

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Obie Fernandez

Posts: 608
Nickname: obie
Registered: Aug, 2005

Obie Fernandez is a Technologist for ThoughtWorks
More on Business DSLs in Ruby Posted: Mar 26, 2006 6:53 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Obie Fernandez.
Original Post: More on Business DSLs in Ruby
Feed Title: Obie On Rails (Has It Been 9 Years Already?)
Feed URL: http://jroller.com/obie/feed/entries/rss
Feed Description: Obie Fernandez talks about life as a technologist, mostly as ramblings about software development and consulting. Nowadays it's pretty much all about Ruby and Ruby on Rails.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Obie Fernandez
Latest Posts From Obie On Rails (Has It Been 9 Years Already?)

Advertisement

This is mainly in response to Danny, who is pondering my description of writing DSLs in Ruby...

He refers to some questions he left me as comments, asking how writing DSLs in Ruby different from using XML/XSLT. It's really different actually, but instead of trying to answer the questions directly (especially since I don't quite understand where he's coming from with them) I think I'll just post some sample code and see if it helps.

I will go ahead and say that I believe in breaking down the distinction between code and data -- the DSL script code below resides in the database and is invoked dynamically when needed. Since it's in the database (manipulated as a property on an ActiveRecord class) then I can use the power of Rails to easily and quickly bolt on all sorts of wonderful access control, workflow and versioning features, with the goal of getting business end-users programming the behavior of the system.

Here is a sample script that I hope illustrates the concepts I've described. The domain is different to protect the privacy of my client, but the syntax is close enough that the intent of writing code this way should be clear. The sample system handles monthly commission payments for a manufacturer's sales representatives.

 In English, the first line reads like "define acme as the sales rep brand code equal to ACME".

define :acme => sales_rep_fact.brand_code.equals('ACME')

define :contraptions => sales_rep_fact.product_line.equals('CONTRAP')
define :explosives => sales_fact.product_line.equals('BOOM')
define :rockets => sales_rep_fact.product_line.equals('ROCKETS')

define :new_rep => sales_rep_fact.contract_date.during(current_month)

define :employee => sales_rep_fact.affiliation_code.equals('S')
define :independent => sales_rep_fact.affiliation_code.equals('I')

define :first_sale => sales_rep_fact.first_sale_date.during(current_month)

define :arizona => sales_rep_fact.address_state_code.equals('AZ')
define :new_mexico => sales_rep_fact.address_state_code.equals('NM')

define :month_revenue => sales_rep_fact.monthly_sales_revenue
define :year_target => sales_rep_fact.yearly_revenue_target
define :number_of_transactions => sales_rep_fact.transaction_count

The sales_rep_fact varible is built-in to the implementation of this DSL. It points to a database view that joins and flattens all the relevant data that might be needed to figure out how to pay a sales rep for a given month. The analyst that is responsible for maintaining this script is already very familiar with this view since he has been accessing via SQL every month and pulling his query results into Excel in order to calculate payouts manually. As you might already have guessed, the variable definitions are criteria which identify properties of sales reps we will use in our payment rules, which follow in the script.

calculate acme, arizona do
pay 10.percent_of(month_revenue), contraptions
pay 12.percent_of(month_revenue), rockets, employee
pay 25.percent_of(month_revenue), rockets, independent
end

calculate acme, new_mexico do
pay 10.percent_of(month_revenue), employee
pay 25.percent_of(month_revenue), independent
end

calculate
pay 5.dollars.times(number_of_transactions), explosives
pay 500.dollars, new_rep, first_sale
accrue 25.percent_of(month_revenue), month_revenue.greater_than(year_target.divided_by 12)
end

The calculate, pay, and accrue methods are also built into this DSL implementation and their meaning should be clear to anyone that's worked on even the most basic accounting systems. In a followup post (coming soon!) I'll delve into some of the wildly differing contexts that can be used with this script, beyond the SQL and XHTML generation that I mentioned in my original Ruby DSLs post.

In summary, what this sample code illustrates is a DSL designed specifically for describing the rules governing commission payments to sales representatives. The goal of this DSL is to enable the maintainers of the commission payments application to accurately program the rules needed to calculate payments on a monthly basis.

Read: More on Business DSLs in Ruby

Topic: Autotest is Better than Ever Previous Topic   Next Topic Topic: My Thoughts on the Ruby Enterprise Debate

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use