มีประเด็นที่น่าสนใจอยู่อันก็คือ Domain Specific Language
The basic idea of a domain specific language (DSL) is a computer language that's targeted to a particular kind of problem, rather than a general purpose language that's aimed at any kind of software problem.
ที่สนใจประเด็นนี้ เพราะว่า Ruby language มันมีความยืดหยุ่นมาก
ทำให้เราสามารถสร้าง Domain Language เพื่อให้เหมาะกับงานของเราได้
อย่างเช่น Rake ที่ออกแบบมาสำหรับ build process
หรือ ActiveRecord ที่ออกแบบมาสำหรับ ORM
ตัวอย่าง Rakefile
task :codeGen do
# do the code generation
end
task :compile => :codeGen do
#do the compilation
end
task :dataLoad => :codeGen do
# load the test data
end
task :test => [:compile, :dataLoad] do
# run the tests
end
ตัวอย่าง ActiveRecord
class Item < ActiveRecord::Base
belongs_to :category
validates_associated :categoory
validates_format_of :done_before_type_case
,:with=>/[01]/,
,:message=>"must be 0 or 1"
validates_presence_of :description
validates_length_of :description
,:maximum=>40
end
จริงๆแล้วพวก syntax ที่เราเห็นนั้น มันก็คือ method ธรรมดานี่แหล่ะ
อย่างเช่น
task :name => [:prereq1, :prereq2]
จริงๆแล้ว ถ้าเขียนให้ดูเป็นขั้นเป็นตอนหน่อย ก็เขียนได้ดังนี้
hash = Hash.new
hash[:name] = [:prereq1, :prereq2]
task(hash)
ถ้าเราไปเปิด source code ของ rake ดูจะเห็นว่า
เขา define method task ไว้ดังนี้
# Declare a basic task.
#
# Example:
# task :clobber => [:clean] do
# rm_rf "html"
# end
#
def task(args, &block)
Task.define_task(args, &block)
end
จะเห็นได้ว่า block do...end ถูก pass เป็น object ไปไว้ในตัวแปร block
เมื่อต้องการ execute ก็เพียงแต่สั่ง
block.call
ใน Rake มี feature Multiple Definitions
ซึ่งเปิดโอกาสให้เราเขียน definition กระจายแบบนี้ได้
task :name
task :name => [:prereq1]
task :name => [:prereq2]
task :name do |t|
# actions
end
feature ที่ทำให้เขียนแบบนี้ได้ มันเป็นคุณสมบัติของ ruby language เลย เช่น
class Person
def initialize(name)
@name = name
end
end
p1 = Person.new("polawat")
class Person
def sayhi
puts "Hello #{@name}."
end
end
p1.sayhi
เห็นได้ว่า เราสามารถ extend class Person
ด้วยการประกาศ definition class ใหม่อีกรอบ
(ไม่มีข้อจำกัดเรื่อง scope เราสามารถ extend class
ของ ruby เช่น String ก็ได้)
อ่านเพิ่มเติม
No comments:
Post a Comment