dsl 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ Rakefile
@@ -0,0 +1,49 @@
1
+ # DSL
2
+
3
+ ## Description
4
+
5
+ dsl.rb is a small script (26 lines) to help create domain specific languages within Ruby.
6
+
7
+ ## Install
8
+
9
+ Until I setup the gem... just clone and play around with it.
10
+
11
+ ## Quick Example
12
+
13
+ require 'dsl'
14
+
15
+ class UserDSL < DSL
16
+ def name(n); @name = n; end
17
+ def gender(g); @gender = g; end
18
+ def age(a); @age = a; end
19
+ end
20
+
21
+ class User
22
+ attr :name, :gender, :age
23
+ dsl_method :edit => UserDSL
24
+ end
25
+
26
+ ryguy = User.new
27
+
28
+ ryguy.edit do
29
+ name 'Ryan Lewis'
30
+ gender :male
31
+ age 19
32
+ end
33
+
34
+ p ryguy
35
+ # => #<User:0x00000001b6dc78 @name="Ryan Lewis", @gender=:male, @age=19>
36
+
37
+ As you can see, simply requiring DSL adds the Module/Class method `dsl_method`, which defines a new instance method for your class that only accepts a block.
38
+
39
+ `dsl_method` only accepts a `Hash`, the key being the instance method name and the value being the DSL class the method will use.
40
+
41
+ When your DSL instance method is called (with a block, of course), all of your object's instance variables are delegated into a new instance of the DSL class assigned to the called DSL instance method.
42
+ The block is then `instance_eval`'d within the new DSL class instance where you can use the instance variables.
43
+ When the block is closed, all of the instance variables are then transfered back to your object.
44
+
45
+ Therefor, creating a Domain Specific Language is as easy as subclassing the `DSL` class. That's it!
46
+
47
+ ## Copyright
48
+
49
+ Copyright (c) 2010 Ryan Lewis. See LICENSE for details.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/dsl.rb ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ class DSL
4
+ def self.call(parent, &blk)
5
+ instance = new
6
+ # Add all of the parents instance variables to the instance
7
+ parent.instance_variables.each do |instance_variable|
8
+ value = parent.instance_variable_get(instance_variable)
9
+ instance.instance_variable_set(instance_variable, value)
10
+ end
11
+ # Instance eval the block in the instance
12
+ instance.instance_eval(&blk)
13
+ # Replace all of the parents instance variables with the instance's
14
+ instance.instance_variables.each do |instance_variable|
15
+ value = instance.instance_variable_get(instance_variable)
16
+ parent.instance_variable_set(instance_variable, value)
17
+ end
18
+ end
19
+ end
20
+
21
+ class Module
22
+ def dsl_method(opts)
23
+ # Complain if the argument isn't a hash
24
+ raise(TypeError) unless opts.is_a?(Hash)
25
+ # For each dsl_method, define it in the class
26
+ # The methods do not accept arguments, only blocks
27
+ opts.each do |method, dsl_class|
28
+ define_method(method) do |&blk|
29
+ raise(ArgumentError, "method #{method} requires a block") unless block_given?
30
+ dsl_class.call(self, &blk)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.join(File.dirname(__FILE__), '..', 'dsl')
4
+
5
+ class Database
6
+ class Table
7
+ def initialize
8
+ @schema = {}
9
+ @entries = []
10
+ end
11
+
12
+ def create(opts)
13
+ raise(TypeError) unless opts.is_a?(Hash)
14
+ opts.each do |name, v|
15
+ raise("key '#{name}' not defined in schema") unless @schema.has_key?(name)
16
+ if @schema[name] == :primary_key
17
+ raise('You cannot set primary keys')
18
+ else
19
+ raise("key '#{name}' not of type #{@schema[name]}") unless v.is_a?(@schema[name])
20
+ end
21
+ end
22
+ @schema.select { |name, v| v == :primary_key }.each do |name, v|
23
+ opts[name] = @entries.count
24
+ end
25
+ @entries << opts
26
+ end
27
+
28
+ def [](id)
29
+ @entries.find_all do |entry|
30
+ entry[:id] == id
31
+ end
32
+ end
33
+ end
34
+
35
+ class SchemaDSL < DSL
36
+ def primary_key(name); @schema[name] = :primary_key; end
37
+ def String(name); @schema[name] = ::String; end
38
+ def Integer(name); @schema[name] = ::Integer; end
39
+ end
40
+
41
+ def initialize
42
+ @tables = {}
43
+ end
44
+
45
+ def table(name, &blk)
46
+ if block_given?
47
+ raise("Table '#{name}' already exists") unless @tables[name].nil?
48
+ @tables[name] = Table.new
49
+ SchemaDSL.call(@tables[name], &blk)
50
+ else
51
+ @tables[name]
52
+ end
53
+ end
54
+ end
55
+
56
+ require 'ap'
57
+
58
+ db = Database.new
59
+
60
+ db.table(:users) do
61
+ primary_key :id
62
+ String :username
63
+ Integer :age
64
+ end
65
+
66
+ db.table(:users).create(:username => 'Foo', :age => 19)
67
+ db.table(:users).create(:username => 'Bar', :age => 43)
68
+
69
+ p db.table(:users)[0]
70
+ # => [{:username=>"Foo", :age=>19, :id=>0}]
71
+
72
+ p db.table(:users)[1]
73
+ # => [{:username=>"Bar", :age=>43, :id=>1}]
74
+
75
+ db.table(:users).create(:username => 'Baz', :age => 'One Hundred')
76
+ # => ERROR: key 'age' not of type Integer (RuntimeError)
77
+
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.join(File.dirname(__FILE__), '..', 'dsl')
4
+
5
+ class UserDSL < DSL
6
+ def name(n); @name = n; end
7
+ def gender(g); @gender = g; end
8
+ def age(a); @age = a; end
9
+ end
10
+
11
+ class User
12
+ attr :name, :gender, :age
13
+ dsl_method :edit => UserDSL
14
+ end
15
+
16
+ ryguy = User.new
17
+
18
+ ryguy.edit do
19
+ name 'Ryan Lewis'
20
+ gender :male
21
+ age 19
22
+ end
23
+
24
+ p ryguy
25
+ # => #<User:0x00000001b6dc78 @name="Ryan Lewis", @gender=:male, @age=19>
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.join(File.dirname(__FILE__), '..', 'dsl')
4
+
5
+ class ConfigDSL < DSL
6
+ def add_helpers(*h)
7
+ @helpers.concat(h)
8
+ end
9
+ end
10
+
11
+ class WebApp
12
+ attr :helpers
13
+ dsl_method :config => ConfigDSL
14
+
15
+ #===--- OR:
16
+ # dsl_method :config => Class.new(DSL) {
17
+ # def add_helpers(*h)
18
+ # @helpers.concat(h)
19
+ # end
20
+ # }
21
+
22
+ #===--- MAYBE:
23
+ # define_dsl_method :config do
24
+ # def add_helpers; end
25
+ # end
26
+
27
+ def initialize
28
+ @helpers = ['helpers/foo', 'helpers/bar']
29
+ end
30
+ end
31
+
32
+ web_app = WebApp.new
33
+
34
+ p web_app.helpers
35
+ # => ["helpers/foo", "helpers/bar"]
36
+
37
+ web_app.config do
38
+ add_helpers 'helpers/baz', 'helpers/qux'
39
+ end
40
+
41
+ p web_app.helpers
42
+ # => ["helpers/foo", "helpers/bar", "helpers/baz", "helpers/qux"]
43
+
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dsl
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Ryan Lewis
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-16 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Easily create Domain Specific Languages with any block. You can also link instance methods to your DSL.
23
+ email: c00lryguy@gmail.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - README.md
30
+ files:
31
+ - .gitignore
32
+ - README.md
33
+ - VERSION
34
+ - dsl.rb
35
+ - examples/database.rb
36
+ - examples/user.rb
37
+ - examples/webapp.rb
38
+ has_rdoc: true
39
+ homepage: http://github.com/c00lryguy/dsl
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options:
44
+ - --charset=UTF-8
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ hash: 3
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ requirements: []
66
+
67
+ rubyforge_project:
68
+ rubygems_version: 1.3.7
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: A small library for creating Domain Specific Languages (DSLs)
72
+ test_files:
73
+ - examples/webapp.rb
74
+ - examples/database.rb
75
+ - examples/user.rb