Class: Caesar
- Inherits:
-
Object
- Object
- Caesar
- Defined in:
- lib/caesar.rb
Overview
Caesar – A simple class for rapid DSL prototyping.
Subclass Caesar, then tell it which attributes have children using Caesar.bloody and which have blocks that you want to execute later using Caesar.virgin. That’s it! Just start drinking! I mean, start writing your domain specific language!
See README.rdoc for a usage example.
Defined Under Namespace
Classes: Hash
Constant Summary collapse
- VERSION =
"0.3.2"
Instance Attribute Summary collapse
-
#caesar_properties ⇒ Object
An instance of Caesar::Hash which contains the data specified by your DSL.
Class Method Summary collapse
-
.bloody(meth, execute = true) ⇒ Object
see bin/example for usage.
-
.inherited(modname) ⇒ Object
Executes automatically when Caesar is subclassed.
-
.virgin(meth) ⇒ Object
see bin/example for usage.
Instance Method Summary collapse
-
#initialize(name = nil) ⇒ Caesar
constructor
Creates an instance of Caesar.
-
#method_missing(name, *args, &b) ⇒ Object
This method handles all of the attributes that do not contain blocks.
Constructor Details
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &b) ⇒ Object
This method handles all of the attributes that do not contain blocks.
33 34 35 36 37 38 39 40 41 |
# File 'lib/caesar.rb', line 33 def method_missing(name, *args, &b) return @caesar_properties[name] if @caesar_properties.has_key?(name) && args.empty? && b.nil? if @caesar_pointer[name] @caesar_pointer[name] = [@caesar_pointer[name]] unless @caesar_pointer[name].is_a?(Array) @caesar_pointer[name] += args elsif !args.empty? @caesar_pointer[name] = args.size == 1 ? args.first : args end end |
Instance Attribute Details
#caesar_properties ⇒ Object
An instance of Caesar::Hash which contains the data specified by your DSL
24 25 26 |
# File 'lib/caesar.rb', line 24 def caesar_properties @caesar_properties end |
Class Method Details
.bloody(meth, execute = true) ⇒ Object
see bin/example for usage.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/caesar.rb', line 47 def self.bloody(meth, execute=true) define_method(meth) do |*names,&b| # |*names,&b| syntax does not parse in Ruby 1.8 all = instance_variable_get("@" << meth.to_s) || [] names.each do |name| instance_variable_set("@" << meth.to_s, all << name) if execute prev = @caesar_pointer @caesar_pointer[name] ||= Caesar::Hash.new @caesar_pointer = @caesar_pointer[name] b.call if b @caesar_pointer = prev else @caesar_pointer[name] = b end end nil end define_method("#{meth}_values") do || instance_variable_get("@" << meth.to_s) || [] end end |
.inherited(modname) ⇒ Object
Executes automatically when Caesar is subclassed. This creates the YourClass::DSL module which contains a single method: method_missing. This is used to catch the top level DSL method. That’s why you can used any method name you like.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/caesar.rb', line 75 def self.inherited(modname) meth = (modname.to_s.split(/::/))[-1].downcase # Some::ClassName => classname module_eval %Q{ module #{modname}::DSL def #{meth}(*args, &b) name = !args.empty? ? args.first.to_s : nil varname = "@#{meth.to_s}" varname << "_\#{name}" if name i = instance_variable_set(varname, #{modname.to_s}.new(name)) i.instance_eval(&b) if b i end end }, __FILE__, __LINE__ end |
.virgin(meth) ⇒ Object
see bin/example for usage.
43 44 45 |
# File 'lib/caesar.rb', line 43 def self.virgin(meth) self.bloody(meth, false) end |