Class: ZTK::DSL::Base

Inherits:
Object
  • Object
show all
Includes:
Core
Defined in:
lib/ztk/dsl/base.rb

Overview

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.

Examples:

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:

Defined Under Namespace

Modules: ClassMethods

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Base) initialize(id = nil, &block)

Returns a new instance of Base



100
101
102
103
104
105
# 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

Class Method Details

+ (Object) extended(base)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



96
97
98
# File 'lib/ztk/dsl/base.rb', line 96

def self.extended(base)
  # NOOP
end

+ (Object) included(base)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



91
92
93
# File 'lib/ztk/dsl/base.rb', line 91

def self.included(base)
  # NOOP
end

+ (Object) inherited(base)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



83
84
85
86
87
88
# 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

Instance Method Details

- (Object) do_block(&block)



107
108
109
110
111
112
113
114
115
116
117
118
119
# 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

- (String) inspect

Instance Inspect

Inspect the DSL object's instance, returning a concise string representation of the instance.

Returns:

  • (String)

    A concise string representation of the instance.



127
128
129
130
131
132
133
# 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