Class: Gamefic::Query::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/gamefic/query/base.rb

Overview

A base class for entity-based queries that can be applied to responses. Each query matches a command token to an object that can be passed into a response callback.

Most queries return entities, but there are also queries for plain text and integers.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*arguments, name: self.class.to_s) ⇒ Base

Returns a new instance of Base.

Parameters:

  • arguments (Array<Object>)
  • name (String) (defaults to: self.class.to_s)

Raises:

  • (ArgumentError)

    if any of the arguments are nil



20
21
22
23
24
25
# File 'lib/gamefic/query/base.rb', line 20

def initialize *arguments, name: self.class.to_s
  raise ArgumentError, "nil argument in query" if arguments.any?(&:nil?)

  @arguments = arguments
  @name = name
end

Instance Attribute Details

#argumentsArray<Object> (readonly)

Returns:



14
15
16
# File 'lib/gamefic/query/base.rb', line 14

def arguments
  @arguments
end

Class Method Details

.plainObject



101
102
103
# File 'lib/gamefic/query/base.rb', line 101

def self.plain
  @plain ||= new
end

.span(subject) ⇒ Object



105
106
107
# File 'lib/gamefic/query/base.rb', line 105

def self.span(subject)
  plain.span(subject)
end

Instance Method Details

#accept?(subject, object) ⇒ Boolean

True if the object is selectable by the subject.

Parameters:

Returns:

  • (Boolean)


65
66
67
# File 'lib/gamefic/query/base.rb', line 65

def accept?(subject, object)
  select(subject).include?(object)
end

#bind(narrative) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/gamefic/query/base.rb', line 93

def bind(narrative)
  clone.tap do |query|
    query.instance_exec do
      @arguments = narrative.unproxy(@arguments)
    end
  end
end

#filter(subject, token) ⇒ Result

Get a query result for a given subject and token.

Parameters:

Returns:



32
33
34
35
36
37
# File 'lib/gamefic/query/base.rb', line 32

def filter(subject, token)
  scan = Scanner.scan(select(subject), token)
  return Result.new(nil, scan.token) unless scan.matched.one?

  Result.new(scan.matched.first, scan.remainder, scan.strictness)
end

#inspectObject



89
90
91
# File 'lib/gamefic/query/base.rb', line 89

def inspect
  "#{name}(#{arguments.map(&:inspect).join(', ')})"
end

#nameObject



85
86
87
# File 'lib/gamefic/query/base.rb', line 85

def name
  @name || self.class.to_s
end

#precision::Integer

The query’s precision. The higher the number, the more specific the query is.

In general terms, a query’s precision is highest if its arguments select for a specific instance of an entity instead of a class of entity.

When a command gets parsed, the resulting list of available actions gets sorted in descending order of their responses’ overall precision, so the action with the highest precision gets attempted first.

Returns:

  • (::Integer)


81
82
83
# File 'lib/gamefic/query/base.rb', line 81

def precision
  @precision ||= calculate_precision
end

#select(subject) ⇒ Array<Entity>

Get an array of entities that match the arguments from the context of the subject.

Parameters:

Returns:



44
45
46
# File 'lib/gamefic/query/base.rb', line 44

def select(subject)
  span(subject).that_are(*arguments)
end

#span(_subject) ⇒ Array<Entity>

Get an array of entities that are candidates for selection from the context of the subject. These are the entities that #select will filter through query’s arguments.

Subclasses should override this method.

Parameters:

Returns:



56
57
58
# File 'lib/gamefic/query/base.rb', line 56

def span(_subject)
  []
end