aska 0.0.2 → 0.0.6

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.
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