Class: RubyLabs::ElizaLab::Pattern
- Inherits:
-
Object
- Object
- RubyLabs::ElizaLab::Pattern
- Defined in:
- lib/elizalab.rb
Overview
Pattern
A Pattern represents one way to transform an input sentence into a response. A Pattern instance has a regular expression and a list of one or more reassembly strings that can refer to groups in the expression. There is also an index to record the last reassembly string used, so the application can cycle through the strings.
Instance Attribute Summary collapse
-
#index ⇒ Object
Returns the value of attribute index.
-
#list ⇒ Object
Returns the value of attribute list.
-
#md ⇒ Object
Returns the value of attribute md.
-
#regexp ⇒ Object
Returns the value of attribute regexp.
Instance Method Summary collapse
-
#add_parens(s, r) ⇒ Object
Helper method called by the constructor – add parentheses around every occurrence of the string
r
in sentence patterns
. -
#add_response(s) ⇒ Object
Add sentence
s
to the set of response strings for this pattern. -
#apply(s, opt = :preprocess) ⇒ Object
Try to apply this pattern to input sentence
s
. -
#cleanRegexp ⇒ Object
Helper method called by inspect and to_s – remove the word boundary anchors from the regular expression so it is easier to read.
-
#initialize(expr, list = []) ⇒ Pattern
constructor
Create a new sentence pattern that will apply to input sentences that match
expr
. -
#inspect ⇒ Object
Create a more detailed string summarizing the pattern and its possible responses.
-
#match(s) ⇒ Object
Helper method – return
true
if sentences
matches the regular expression for this pattern. -
#parts ⇒ Object
Helper method – return an array of parts of the input sentence captured when the input was compared to the regular expression and that matched any wild cards or groups in the regular expression.
-
#reset ⇒ Object
Reset the internal counter in this pattern, so that the next response comes from the first response string.
-
#to_s ⇒ Object
Create a string that summarizes the attributes of this pattern.
Constructor Details
#initialize(expr, list = []) ⇒ Pattern
Create a new sentence pattern that will apply to input sentences that match expr
. The argument can be either a string or a regular expression. If the argument is a string, it is converted to a regular expression that matches exactly that string, e.g. “duck” is converted to /duck/.
To make it easier for uses to create patterns without knowing too many details of regular expressions the constructor modifies the regular expression:
- word breaks
-
Insert word break anchors before the first word and after the last word in the expression
- case insensitive
-
Add a i modifier to the regular expression
- wildcards
-
Insert parentheses around “.*”
- variables
-
Insert parentheses around variable names of the form “$n”
- alternatives
-
Insert parentheses around groups of words, e.g. “a|b|c”
To see the real final regular expression stored with a rule call the regexp
accessor method.
Example:
>> p = Pattern.new("duck")
=> duck: []
>> p.regexp
=> /\bduck\b/i
>> p = Pattern.new("plane|train|automobile")
=> (plane|train|automobile): []
>> p.regexp
=> /(plane|train|automobile)/i
>> p = Pattern.new("I don't like .*")
=> I don't like (.*): []
>> p.regexp
=> /\bI don't like (.*)/i
– Pattern.new called internally only from Rule#addPattern, which is called to add /.*/ for default rule, or when reading /…/ line from script.
In interactive experiments, users can call Pattern.new(s) or Pattern.new(s,a) where s is a string or regexp, and a is an array of response strings.
185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/elizalab.rb', line 185 def initialize(expr, list = []) raise "Pattern#initialize: expr must be String or Regexp" unless (expr.class == String || expr.class == Regexp) re = (expr.class == String) ? expr : expr.source add_parens(re, /\(?\.\*\)?/ ) add_parens(re, /\(?[\w' ]+(\|[\w' ]+)+\)?/ ) add_parens(re, /\(?\$\w+\)?/ ) re.insert(0,'\b') if re =~ /^\w/ re.insert(-1,'\b') if re =~ /\w$/ @regexp = Regexp.new(re, :IGNORECASE) @list = list.nil? ? Array.new : list @index = 0 end |
Instance Attribute Details
#index ⇒ Object
Returns the value of attribute index.
145 146 147 |
# File 'lib/elizalab.rb', line 145 def index @index end |
#list ⇒ Object
Returns the value of attribute list.
145 146 147 |
# File 'lib/elizalab.rb', line 145 def list @list end |
#md ⇒ Object
Returns the value of attribute md.
145 146 147 |
# File 'lib/elizalab.rb', line 145 def md @md end |
#regexp ⇒ Object
Returns the value of attribute regexp.
145 146 147 |
# File 'lib/elizalab.rb', line 145 def regexp @regexp end |
Instance Method Details
#add_parens(s, r) ⇒ Object
Helper method called by the constructor – add parentheses around every occurrence of the string r
in sentence pattern s
. Checks to make sure there aren’t already parentheses there.
209 210 211 |
# File 'lib/elizalab.rb', line 209 def add_parens(s, r) s.gsub!(r) { |m| ( m[0] == ?( ) ? m : "(" + m + ")" } end |
#add_response(s) ⇒ Object
Add sentence s
to the set of response strings for this pattern.
215 216 217 |
# File 'lib/elizalab.rb', line 215 def add_response(s) @list << s end |
#apply(s, opt = :preprocess) ⇒ Object
Try to apply this pattern to input sentence s
. If s
matches the regular expression for this rule, extract the parts that match groups, insert them into the next response string, and return the result. If s
does not match the regular expression return nil
.
The second argument should be a symbol that controls whether or not the method applies preprocessing rules. The default is to apply preprocessing, which is the typical case when users call the method from an IRB session. But when Eliza is running, preprocessing is done already, so this argument is set to :no_preprocess.
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/elizalab.rb', line 229 def apply(s, opt = :preprocess) Eliza.preprocess(s) if opt == :preprocess @md = s.match(@regexp) return nil if @list.empty? || @md == nil res = @list[inc()].clone return res if res[0] == ?@ puts "reassembling '#{res}'" if @@verbose res.gsub!(/\$\d+/) do |ns| n = ns.slice(1..-1).to_i # strip leading $, convert to int if n && @md[n] puts "postprocess #{@md[n]}" if @@verbose @md[n].gsub(/[a-z\-$']+/i) do |w| (@@post.has_key?(w) && @@post[w][0] != ?$) ? @@post[w] : w end else warn "Pattern.apply: no match for #{ns} in '#{res}'" "" end end return res end |
#cleanRegexp ⇒ Object
Helper method called by inspect and to_s – remove the word boundary anchors from the regular expression so it is easier to read.
284 285 286 287 288 |
# File 'lib/elizalab.rb', line 284 def cleanRegexp res = @regexp.source res.gsub!(/\\b/,"") return res end |
#inspect ⇒ Object
Create a more detailed string summarizing the pattern and its possible responses.
277 278 279 |
# File 'lib/elizalab.rb', line 277 def inspect return cleanRegexp + ": " + @list.inspect end |
#match(s) ⇒ Object
Helper method – return true
if sentence s
matches the regular expression for this pattern.
254 255 256 257 |
# File 'lib/elizalab.rb', line 254 def match(s) @md = s.match(@regexp) return @md != nil end |
#parts ⇒ Object
Helper method – return an array of parts of the input sentence captured when the input was compared to the regular expression and that matched any wild cards or groups in the regular expression.
263 264 265 |
# File 'lib/elizalab.rb', line 263 def parts return @md.nil? ? nil : @md.captures end |
#reset ⇒ Object
Reset the internal counter in this pattern, so that the next response comes from the first response string.
201 202 203 |
# File 'lib/elizalab.rb', line 201 def reset @index = 0 end |
#to_s ⇒ Object
Create a string that summarizes the attributes of this pattern.
269 270 271 272 273 |
# File 'lib/elizalab.rb', line 269 def to_s s = " /" + cleanRegexp + "/\n" @list.each { |x| s += " \"" + x + "\"\n" } return s end |