Created
September 15, 2012 14:59
-
-
Save davybrion/3728369 to your computer and use it in GitHub Desktop.
code snippets for "Writing A Simple DSL" post
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'forwardable' | |
class Model | |
extend Forwardable | |
def initialize | |
@entities = [] | |
end | |
def add_entity(entity) | |
@entities << entity | |
end | |
def entity_for(name) | |
@entities.detect { |entity| entity.name == name } | |
end | |
def_delegator :@entities, :each, :each_entity | |
end | |
class Entity | |
extend Forwardable | |
attr_reader :name | |
def initialize(name) | |
@name = name | |
@collections = [] | |
@properties = [] | |
@references = [] | |
end | |
def add_collection(collection) | |
@collections << collection | |
end | |
def add_property(property) | |
@properties << property | |
end | |
def add_reference(reference) | |
@references << reference | |
end | |
def identifier | |
@properties.detect { |property| property.is_identifier? } | |
end | |
def_delegator :@collections, :each, :each_collection | |
def_delegator :@properties, :each, :each_property | |
def_delegator :@references, :each, :each_reference | |
end | |
class Property | |
attr_reader :name | |
attr_reader :required | |
attr_reader :type | |
def self.new_identifier(name, type) | |
self.new(name, type, false, true) | |
end | |
def initialize(name, type, required=false, is_identifier=false) | |
@name = name | |
@type = type | |
@required = required | |
@is_identifier = is_identifier | |
end | |
def is_identifier? | |
@is_identifier | |
end | |
end | |
class Reference | |
attr_reader :name | |
attr_reader :entity | |
attr_reader :is_required | |
def initialize(name, entity, is_required) | |
@name = name | |
@entity = entity | |
@is_required = is_required | |
end | |
end | |
class Reference | |
attr_reader :name | |
attr_reader :entity | |
attr_reader :is_required | |
def initialize(name, entity, is_required) | |
@name = name | |
@entity = entity | |
@is_required = is_required | |
end | |
end | |
class Collection | |
attr_reader :name | |
attr_reader :entity | |
def initialize(name, entity) | |
@name = name | |
@entity = entity | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
entity "Invoice" | |
identified_by "Id", :guid | |
must_reference "Customer" | |
must_have "Date", :date | |
can_have "Discount", :double | |
contains "Lines", "InvoiceLine" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require_relative 'application.rb' | |
require_relative 'entity.rb' | |
require_relative 'collection.rb' | |
require_relative 'property.rb' | |
require_relative 'reference.rb' | |
@model = Model.new | |
def entity(name) | |
entity = Entity.new(name) | |
@model.add_entity entity | |
@current_entity = entity | |
end | |
def identified_by(name, type) | |
@current_entity.add_property Property.new_identifier(name, type) | |
end | |
def must_have(name, type) | |
has name, type, true | |
end | |
def can_have(name, type) | |
has name, type, false | |
end | |
def must_reference(entity_name, name=nil) | |
references entity_name, true, name | |
end | |
def can_reference(entity_name, name=nil) | |
references entity_name, false, name | |
end | |
def contains(name, entity_name) | |
referred_entity = @model.entity_for entity_name | |
@current_entity.add_collection Collection.new(name, referred_entity) | |
end | |
def has(name, type, required=false) | |
@current_entity.add_property Property.new(name, type, required) | |
end | |
def references(entity_name, is_required=false, name=nil) | |
referred_entity = @model.entity_for entity_name | |
name = entity_name if name.nil? | |
@current_entity.add_reference Reference.new(name, entity_name, is_required) | |
end | |
Dir.glob('*_def.rb').each do |file| | |
@current_entity = nil | |
load file | |
end | |
@model.each_entity do |entity| | |
puts entity.name | |
print_name = Proc.new { |item| puts "\t\t#{item.name}"} | |
puts "\t has the following properties:" | |
entity.each_property &print_name | |
puts "\t has the following references:" | |
entity.each_reference &print_name | |
puts "\t has the following collections:" | |
entity.each_collection &print_name | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Dir.glob('*_def.rb').each do |file| | |
@current_entity = nil | |
load file | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
entity "Customer" | |
identified_by "Id", :guid | |
must_have "Name", :string | |
can_have "Email", :string | |
entity "Product" | |
identified_by "Id", :guid | |
must_have "Name", :string | |
must_have "Price", :integer | |
entity "InvoiceLine" | |
identified_by "Id", :guid | |
must_reference "Product" | |
must_have "Count", :integer | |
entity "Invoice" | |
identified_by "Id", :guid | |
must_reference "Customer" | |
must_have "Date", :date | |
can_have "Discount", :double | |
contains "Lines", "InvoiceLine" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@model.each_entity do |entity| | |
puts entity.name | |
print_name = Proc.new { |item| puts "\t\t#{item.name}"} | |
puts "\t has the following properties:" | |
entity.each_property &print_name | |
puts "\t has the following references:" | |
entity.each_reference &print_name | |
puts "\t has the following collections:" | |
entity.each_collection &print_name | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Customer | |
has the following properties: | |
Id | |
Name | |
has the following references: | |
has the following collections: | |
Invoice | |
has the following properties: | |
Id | |
Date | |
Discount | |
has the following references: | |
Customer | |
has the following collections: | |
Lines | |
InvoiceLine | |
has the following properties: | |
Id | |
Count | |
has the following references: | |
Product | |
has the following collections: | |
Product | |
has the following properties: | |
Id | |
Name | |
Price | |
has the following references: | |
has the following collections: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment