class ZTK::DSL::Base
Generic Domain-specific Language Interface
This module allows you to easily add attributes and relationships to classes to create a custom DSL
in no time.
You can then access these classes in manners similar to what ActiveRecord provides for relationships. You can easily link classes together; load stored objects from Ruby rb files (think Opscode Chef DSL
).
I intend the interface to act like ActiveRecord for the programmer and a nice DSL
for the end user. It's not meant to be a database; more like a soft dataset in memory; extremely fast but highly volitale. As always you can never have your cake and eat it too.
You specify the “schema” in the classes itself; there is no data storage at this time, but I do plan to add support for loading/saving datasets to disk. Keep in mind since you do not specify type constrants in Ruby, one can assign any object to an attribute.
At this time if you do not specify an ID; one is auto generated.
If you wish to create objects in a nested fashion the outer most object must be started using the class name initializer. Once inside the block you can start using the relationship names and do not need to call any further class initializers.
You can also instantiate classes separately and associate them after the fact. That is not shown in this example.
@example Building infrastructure DSL
objects
class Network < ZTK::DSL::Base has_many :servers attribute :name attribute :gw attribute :network attribute :netmask end class Server < ZTK::DSL::Base belongs_to :network attribute :name end Network.new do id :leet_net name "leet-net" gw "7.3.3.1" network "7.3.3.0" netmask "255.255.255.0" server do name "leet-server" end server do id :my_server name "my-server" end server do name "dev-server" end end Network.count Network.all Network.find(:leet_net) Server.count Server.all Server.find(:my_server)
@author Zachary Patten <zpatten AT jovelabs DOT io>
Public Class Methods
@api private
# File lib/ztk/dsl/base.rb, line 96 def self.extended(base) # NOOP end
@api private
# File lib/ztk/dsl/base.rb, line 91 def self.included(base) # NOOP end
@api private
# File lib/ztk/dsl/base.rb, line 83 def self.inherited(base) base.send(:extend, ZTK::DSL::Base::ClassMethods) base.instance_eval do attribute :id end end
# File lib/ztk/dsl/base.rb, line 100 def initialize(id=nil, &block) self.id = (id || self.class.next_id) self.class.dataset << self do_block(&block) end
Public Instance Methods
# File lib/ztk/dsl/base.rb, line 107 def do_block(&block) if block_given? if (block.arity < 1) instance_eval(&block) else block.call(self) end end if (self.class.dataset.count{ |data| (data.id == self.id) } > 1) raise StandardError, "Primary key '#{self.id}' already exists!" end end
Instance Inspect
Inspect the DSL
object's instance, returning a concise string representation of the instance.
@return [String] A concise string representation of the instance.
# File lib/ztk/dsl/base.rb, line 127 def inspect details = Array.new details << "attributes=#{attributes.inspect}" if attributes.count > 0 details << "has_many_references=#{@has_many_references.count}" if @has_many_references details << "belongs_to_references=#{@belongs_to_references.count}" if @belongs_to_references "#<#{self.class.to_s} id=#{self.id.inspect} #{details.join(', ')}>" end