aska 0.0.2 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (9) hide show
  1. data/CHANGELOG +9 -2
  2. data/Manifest +2 -0
  3. data/README +12 -0
  4. data/Rakefile +72 -0
  5. data/aska.gemspec +80 -24
  6. data/lib/aska.rb +71 -26
  7. data/lib/object.rb +6 -0
  8. data/spec/rules_spec.rb +61 -13
  9. metadata +31 -13
data/CHANGELOG CHANGED
@@ -1,2 +1,9 @@
1
- v0.0.2 Added buckets of rules
2
- v0.0.1 First write
1
+ v0.0.5 * Rewrite of adding rules method
2
+ v0.0.4 * Added lookup methods
3
+ * Added supported methods
4
+ * Updated README
5
+ * Renamed all the attr_accessors and namespaced them inside aska
6
+ v0.0.3 * Changed the methodology of storing the rules
7
+ * Removed evaluation
8
+ v0.0.2 * Added buckets of rules
9
+ v0.0.1 * First write
data/Manifest CHANGED
@@ -1,8 +1,10 @@
1
1
  aska.gemspec
2
2
  CHANGELOG
3
3
  lib/aska.rb
4
+ lib/object.rb
4
5
  LICENSE
5
6
  Manifest
7
+ Rakefile
6
8
  README
7
9
  spec/rules_spec.rb
8
10
  spec/spec_helper.rb
data/README CHANGED
@@ -25,13 +25,25 @@
25
25
 
26
26
  @car.rules_valid?(:names)
27
27
 
28
+ Currently, the methods that are supported are: < > == => =< to check the rules against
29
+
30
+ Aska will try to call the method name given if the method exists on the object, or it will revert to a self-created attribute (named: METHODNAME_aska, if you are curious). This way it does not overwrite any methods on accident and you have access to the data.
31
+
32
+ This rewrite does not use eval on each check.
33
+
28
34
  If they do all match, then the rules_valid? will return true, otherwise it will return false
29
35
 
36
+ You can check if a set of rules exist with: are_rules?(:rules)
37
+ You can check look up the rules manually with: look_up_rules(:rules)
38
+
30
39
  == INSTALL:
31
40
 
32
41
  gem install aska
33
42
 
34
43
  == ROADMAP
44
+ * v0.0.4 - Namespace rules
45
+ * v0.0.3 - Remove eval from the evaluation of rules
46
+ * v0.0.2 - Add buckets for rules
35
47
  * v0.0.1 - First release
36
48
 
37
49
  == LICENSE:
data/Rakefile ADDED
@@ -0,0 +1,72 @@
1
+ begin
2
+ require 'echoe'
3
+ Echoe.new("aska") do |p|
4
+ p.author = "Ari Lerner"
5
+ p.email = "ari.lerner@citrusbyte.com"
6
+ p.summary = "The basics of an expert system"
7
+ p.url = "http://blog.citrusbyte.com"
8
+ p.dependencies = []
9
+ p.version = "0.0.6"
10
+ p.install_message =<<-EOM
11
+
12
+ Aska - Expert system basics
13
+
14
+ See blog.citrusbyte.com for more details
15
+ *** Ari Lerner @ <ari.lerner@citrusbyte.com> ***
16
+
17
+ EOM
18
+ p.include_rakefile = true
19
+ end
20
+ rescue Exception => e
21
+
22
+ end
23
+
24
+ namespace(:pkg) do
25
+ ## Rake task to create/update a .manifest file in your project, as well as update *.gemspec
26
+ desc %{Update ".manifest" with the latest list of project filenames. Respect\
27
+ .gitignore by excluding everything that git ignores. Update `files` and\
28
+ `test_files` arrays in "*.gemspec" file if it's present.}
29
+ task :manifest do
30
+ list = Dir['**/*'].sort
31
+ spec_file = Dir['*.gemspec'].first
32
+ list -= [spec_file] if spec_file
33
+
34
+ File.read('.gitignore').each_line do |glob|
35
+ glob = glob.chomp.sub(/^\//, '')
36
+ list -= Dir[glob]
37
+ list -= Dir["#{glob}/**/*"] if File.directory?(glob) and !File.symlink?(glob)
38
+ puts "excluding #{glob}"
39
+ end
40
+
41
+ if spec_file
42
+ spec = File.read spec_file
43
+ spec.gsub! /^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx do
44
+ assignment = $1
45
+ bunch = $2 ? list.grep(/^test\//) : list
46
+ '%s%%w(%s)' % [assignment, bunch.join(' ')]
47
+ end
48
+
49
+ File.open(spec_file, 'w') {|f| f << spec }
50
+ end
51
+ File.open('Manifest', 'w') {|f| f << list.join("\n") }
52
+ end
53
+ desc "Build gemspec for github"
54
+ task :gemspec => :manifest do
55
+ require "yaml"
56
+ `rake manifest gem`
57
+ data = YAML.load(open("aska.gemspec").read).to_ruby
58
+ File.open("aska.gemspec", "w+") {|f| f << data }
59
+ end
60
+ desc "Update gemspec with the time"
61
+ task :gemspec_update => :gemspec do
62
+ end
63
+ desc "Get ready to release the gem"
64
+ task :prerelease => :gemspec_update do
65
+ `git add .`
66
+ `git ci -a -m "Updated gemspec for github"`
67
+ end
68
+ desc "Release them gem to the gem server"
69
+ task :release => :prerelease do
70
+ `git push origin master`
71
+ end
72
+ end
data/aska.gemspec CHANGED
@@ -1,31 +1,87 @@
1
1
 
2
- # Gem::Specification for Aska-0.0.2
2
+ # Gem::Specification for Aska-0.0.6
3
3
  # Originally generated by Echoe
4
4
 
5
- Gem::Specification.new do |s|
6
- s.name = %q{aska}
7
- s.version = "0.0.2"
5
+ --- !ruby/object:Gem::Specification
6
+ name: aska
7
+ version: !ruby/object:Gem::Version
8
+ version: 0.0.6
9
+ platform: ruby
10
+ authors:
11
+ - Ari Lerner
12
+ autorequire:
13
+ bindir: bin
8
14
 
9
- s.specification_version = 2 if s.respond_to? :specification_version=
15
+ date: 2008-10-31 00:00:00 -07:00
16
+ default_executable:
17
+ dependencies:
18
+ - !ruby/object:Gem::Dependency
19
+ name: echoe
20
+ type: :development
21
+ version_requirement:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: "0"
27
+ version:
28
+ description: The basics of an expert system
29
+ email: ari.lerner@citrusbyte.com
30
+ executables: []
10
31
 
11
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
- s.authors = [""]
13
- s.date = %q{2008-05-28}
14
- s.description = %q{}
15
- s.email = %q{}
16
- s.extra_rdoc_files = ["CHANGELOG", "lib/aska.rb", "LICENSE", "README"]
17
- s.files = ["aska.gemspec", "CHANGELOG", "lib/aska.rb", "LICENSE", "Manifest", "README", "spec/rules_spec.rb", "spec/spec_helper.rb"]
18
- s.has_rdoc = true
19
- s.homepage = %q{}
20
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Aska", "--main", "README"]
21
- s.require_paths = ["lib"]
22
- s.rubyforge_project = %q{aska}
23
- s.rubygems_version = %q{1.0.1}
24
- s.summary = %q{}
25
- end
32
+ extensions: []
26
33
 
34
+ extra_rdoc_files:
35
+ - CHANGELOG
36
+ - lib/aska.rb
37
+ - lib/object.rb
38
+ - LICENSE
39
+ - README
40
+ files:
41
+ - aska.gemspec
42
+ - CHANGELOG
43
+ - lib/aska.rb
44
+ - lib/object.rb
45
+ - LICENSE
46
+ - Manifest
47
+ - Rakefile
48
+ - README
49
+ - spec/rules_spec.rb
50
+ - spec/spec_helper.rb
51
+ has_rdoc: true
52
+ homepage: http://blog.citrusbyte.com
53
+ post_install_message: |+
54
+
55
+ Aska - Expert system basics
56
+
57
+ See blog.citrusbyte.com for more details
58
+ *** Ari Lerner @ <ari.lerner@citrusbyte.com> ***
59
+
60
+ rdoc_options:
61
+ - --line-numbers
62
+ - --inline-source
63
+ - --title
64
+ - Aska
65
+ - --main
66
+ - README
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "="
78
+ - !ruby/object:Gem::Version
79
+ version: "1.2"
80
+ version:
81
+ requirements: []
27
82
 
28
- # # Original Rakefile source (requires the Echoe gem):
29
- #
30
- # require 'echoe'
31
- # Echoe.new('aska')
83
+ rubyforge_project: aska
84
+ rubygems_version: 1.2.0
85
+ specification_version: 2
86
+ summary: The basics of an expert system
87
+ test_files: []
data/lib/aska.rb CHANGED
@@ -1,23 +1,44 @@
1
- $:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
2
-
3
- Dir["aska/**"].each {|a| require a }
4
-
1
+ =begin rdoc
2
+ Aska
3
+ =end
4
+ require "#{File.dirname(__FILE__)}/object"
5
5
  module Aska
6
6
  module ClassMethods
7
- def rules(name=:rules, str="")
8
- r = look_up_rules(name)
9
- str.each_line do |line|
10
- k = line[/(.+)[=\\\<\>](.*)/, 1].gsub(/\s+/, '')
11
- v = line[/(.+)[=\\<>](.*)/, 0].gsub(/\s+/, '')
12
- r << {k => v}
7
+ def rules(name=:rules, arr=[])
8
+ returning look_up_rules(name) do |rs|
9
+ arr.each do |line|
10
+ k = line[/(.+)[=\\\<\>](.*)/, 1].gsub(/\s+/, '')
11
+ v = line[/(.+)[=\\<>](.*)/, 2].gsub(/\s+/, '')
12
+ m = line[/[=\\<>]/, 0].gsub(/\s+/, '')
13
+
14
+ create_instance_variable(k)
15
+ rs << {k => [m, v]}
16
+ end
17
+ self.send(:define_method, name) do
18
+ look_up_rules(name)
19
+ end
13
20
  end
14
21
  end
22
+ def create_instance_variable(k)
23
+ aska_attr_accessors << k.to_sym unless aska_attr_accessors.include?(k.to_sym)
24
+ attr_reader k.to_sym unless respond_to?("#{k}".to_sym)
25
+ attr_writer k.to_sym unless respond_to?("#{k}=".to_sym)
26
+ end
15
27
  def look_up_rules(name)
16
- defined_rules["#{name}"] ||= []
28
+ defined_rules[name.to_sym] ||= []
29
+ end
30
+ def are_rules?(name)
31
+ !look_up_rules(name).empty?
32
+ end
33
+ def aska_attr_accessors
34
+ @@aska_attr_accessors ||= []
17
35
  end
18
36
  def defined_rules
19
37
  @defined_rules ||= {}
20
38
  end
39
+ def aska_named(name)
40
+ "#{name}_aska"
41
+ end
21
42
  end
22
43
 
23
44
  module InstanceMethods
@@ -25,31 +46,55 @@ module Aska
25
46
  @rules ||= self.class.defined_rules
26
47
  end
27
48
  def valid_rules?(name=:rules)
28
- self.class.look_up_rules(name).each do |rule|
29
- return false unless valid_rule?(rule, name)
49
+ self.class.look_up_rules(name).reject {|rule| valid_rule?(rule) }.empty?
50
+ end
51
+ def __aska_aska_stuff(m)
52
+ if respond_to?(m.to_sym)
53
+ self.send(m.to_sym)
54
+ else
55
+ m
30
56
  end
31
- return true
32
57
  end
33
- def valid_rule?(rule, rules)
34
- return false unless rule # Can't apply a rule that is nil, can we?
58
+ def valid_rule?(rule)
35
59
  rule.each do |key,value|
36
60
  begin
37
- return eval(value)
61
+ # puts "#{aska(key)} #{value[0].to_sym} #{get_var(value[1])} (#{attr_accessor?(value[1])})"
62
+ return __aska_aska_stuff(key).send(value[0].to_sym, __aska_get_var(value[1]))
38
63
  rescue Exception => e
39
64
  return false
40
65
  end
41
66
  end
42
67
  end
43
- def method_missing(m, *args)
44
- if self.class.defined_rules.has_key?("#{m}")
45
- self.class.send(:define_method, m) do
46
- self.class.look_up_rules(m)
47
- end
48
- self.send m
49
- else
50
- super
51
- end
68
+ # Get the variable from the class
69
+ # If it's defined as an attr_accessor, we know it has been defined as a rule
70
+ # Otherwise, if we are passing it as a
71
+ def __aska_get_var(name)
72
+ # attr_accessor?(name) ? aska(name) :
73
+ (supported_method?(name) ? name.to_sym : name.to_f)
74
+ end
75
+ def __aska_aska(name)
76
+ self.class.aska_named(name)
77
+ end
78
+ def attr_accessor?(name)
79
+ self.class.aska_attr_accessors.include?(name.to_sym)
80
+ end
81
+ def supported_method?(meth)
82
+ %w(< > == => =<).include?("#{meth}")
52
83
  end
84
+
85
+ def look_up_rules(r);self.class.look_up_rules(r);end
86
+ def are_rules?(r);self.class.are_rules?(r);end
87
+
88
+ # def method_missing(m, *args, &block)
89
+ # if self.class.defined_rules.has_key?(m.to_sym)
90
+ # self.class.send(:define_method, m) do
91
+ # self.class.look_up_rules(m)
92
+ # end
93
+ # self.send m
94
+ # else
95
+ # super
96
+ # end
97
+ # end
53
98
  end
54
99
 
55
100
  def self.included(receiver)
data/lib/object.rb ADDED
@@ -0,0 +1,6 @@
1
+ class Object
2
+ def returning(receiver)
3
+ yield receiver
4
+ receiver
5
+ end
6
+ end
data/spec/rules_spec.rb CHANGED
@@ -2,12 +2,11 @@ require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
3
  class Car
4
4
  include Aska
5
- attr_accessor :x, :y
6
- rules :names, <<-EOR
7
- x > 0
8
- y > 0
9
- x > y
10
- EOR
5
+ rules :names, [
6
+ "x > 0",
7
+ "y > 0",
8
+ "x > y"
9
+ ]
11
10
  end
12
11
  describe "Rules" do
13
12
  before(:each) do
@@ -19,19 +18,63 @@ describe "Rules" do
19
18
  it "should be able to look up the rules based on the name into an array" do
20
19
  @car.names.class.should == Array
21
20
  end
22
- it "should be able to parse the rules lines into an array" do
23
- @car.names.include?({"x"=>"x>0"}).should == true
24
- @car.names.include?({"x"=>"x>y"}).should == true
25
- @car.names.include?({"y"=>"y>0"}).should == true
21
+ it "should be able to say that rules are defined when they are defined" do
22
+ @car.names.should_not be_nil
23
+ end
24
+ it "should be able tos ay that rules are not defined when they are not defined" do
25
+ @car.look_up_rules(:cars_and_wheels).should be_empty
26
+ end
27
+ it "should be able to say if the rules are not rules" do
28
+ @car.are_rules?(:cars_and_wheels).should be_false
29
+ end
30
+ it "should be able to say that rules are rules" do
31
+ @car.are_rules?(:names).should be_true
32
+ end
33
+ describe "parsing" do
34
+ it "should be able to parse the x > 0 into an array" do
35
+ @car.names.include?({"x"=>[">","0"]}).should == true
36
+ end
37
+ it "should be able to parse y > 0 into an array" do
38
+ @car.names.include?({"y"=>[">","0"]}).should == true
39
+ end
40
+ it "should be able to parse x > y into the hash" do
41
+ @car.names.include?({"x"=>[">","y"]}).should == true
42
+ end
43
+ it "should have 3 rules" do
44
+ @car.names.size.should == 3
45
+ end
46
+ it "should be able to look up the names as a rule" do
47
+ Car.look_up_rules(:names).should == [{"x"=>[">", "0"]}, {"y"=>[">", "0"]}, {"x"=>[">", "y"]}]
48
+ end
49
+ end
50
+ # it "should use x if available instead of x_aska" do
51
+ # @car.x = 6
52
+ # @car.get_var(:x).class.should == @car.x_aska.class
53
+ # end
54
+ # it "should be able to get the variable associated with the instance and return it" do
55
+ # @car.x_aska = 4
56
+ # @car.get_var(:x).class.should == @car.x_aska.class
57
+ # end
58
+ it "should be able to get a number with the instance and return it as a float" do
59
+ @car.__aska_get_var(4).class.should == Float
60
+ end
61
+ it "should be able to get the method it's applying as a method symbol" do
62
+ @car.__aska_get_var(:<).class.should == Symbol
63
+ end
64
+ it "should be able to get the method as a symbol" do
65
+ @car.__aska_get_var("<").class.should == Symbol
66
+ end
67
+ it "should be able to retrieve the value of the rule when checking if it's valid" do
68
+ @car.x = 10
69
+ @car.valid_rule?({:x => [:==, 10]}).should == true
26
70
  end
27
71
  it "should be able to apply the rules and say that they are not met when they aren't" do
28
- @car.x = 0
29
72
  @car.valid_rules?(:names).should == false
30
73
  end
31
74
  it "should be able to apply the rules and say they aren't valid when they aren't all met" do
32
75
  @car.x = 5
33
76
  @car.y = 10
34
- @car.valid_rules?(:names).should == false
77
+ @car.valid_rules?(:names).should == true
35
78
  end
36
79
  it "should be able to apply the rules and say they aren't valid when they aren't all met" do
37
80
  @car.x = 5
@@ -40,7 +83,12 @@ describe "Rules" do
40
83
  end
41
84
  it "should be able to apply the rules and say that they are in fact valid" do
42
85
  @car.x = 10
43
- @car.y = 5
86
+ @car.y = 5
44
87
  @car.valid_rules?(:names).should == true
45
88
  end
89
+ it "should have the rules in an array of hashes" do
90
+ @car.names.each do |n|
91
+
92
+ end
93
+ end
46
94
  end
metadata CHANGED
@@ -1,20 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aska
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
- - ""
7
+ - Ari Lerner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-05-28 00:00:00 -07:00
12
+ date: 2008-10-31 00:00:00 -07:00
13
13
  default_executable:
14
- dependencies: []
15
-
16
- description: ""
17
- email: ""
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: echoe
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: The basics of an expert system
26
+ email: ari.lerner@citrusbyte.com
18
27
  executables: []
19
28
 
20
29
  extensions: []
@@ -22,20 +31,29 @@ extensions: []
22
31
  extra_rdoc_files:
23
32
  - CHANGELOG
24
33
  - lib/aska.rb
34
+ - lib/object.rb
25
35
  - LICENSE
26
36
  - README
27
37
  files:
28
38
  - aska.gemspec
29
39
  - CHANGELOG
30
40
  - lib/aska.rb
41
+ - lib/object.rb
31
42
  - LICENSE
32
43
  - Manifest
44
+ - Rakefile
33
45
  - README
34
46
  - spec/rules_spec.rb
35
47
  - spec/spec_helper.rb
36
48
  has_rdoc: true
37
- homepage: ""
38
- post_install_message:
49
+ homepage: http://blog.citrusbyte.com
50
+ post_install_message: |+
51
+
52
+ Aska - Expert system basics
53
+
54
+ See blog.citrusbyte.com for more details
55
+ *** Ari Lerner @ <ari.lerner@citrusbyte.com> ***
56
+
39
57
  rdoc_options:
40
58
  - --line-numbers
41
59
  - --inline-source
@@ -53,16 +71,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
53
71
  version:
54
72
  required_rubygems_version: !ruby/object:Gem::Requirement
55
73
  requirements:
56
- - - ">="
74
+ - - "="
57
75
  - !ruby/object:Gem::Version
58
- version: "0"
76
+ version: "1.2"
59
77
  version:
60
78
  requirements: []
61
79
 
62
80
  rubyforge_project: aska
63
- rubygems_version: 1.0.1
81
+ rubygems_version: 1.2.0
64
82
  signing_key:
65
83
  specification_version: 2
66
- summary: ""
84
+ summary: The basics of an expert system
67
85
  test_files: []
68
86