Known knowns #
Suppose we wanted to list everything we know about Alice. To do this, try:
engine.each("Alice", :_, :_) do |elem|
puts "Alice's #{elem.predicate} is #{elem.object}"
end
#each
takes a pattern and iterates over all known facts matching that pattern. :_
here is a wildcard that matches anything.
You can also call #each
with a single three-element array argument, or with no arguments at all, in which case it will iterate over the entire fact set.
#find
is similar, but it returns the first matching fact.
Entity iterators #
Walking the facts directly can be a bit verbose. If a lot of your lookups use a pattern like {x, _, _}
, entity iterators are more convenient.
Try:
alice = engine.entity("Alice")
This gives you access to the following:
#each
#
alice.each do |predicate, object|
puts "Alice's #{predicate} is #{object}"
end
#each
returns a standard Enumerator
, so you can do all normal enumeratory things with it. Be wary of calling #to_h
on it though: it is possible to have several objects for the same predicate. If Alice has more than one friend, the last matching one will be included in the returned hash. This will be inconsistent with other accessors, which will return the first matching one.
#get
/ #[]
#
puts "Alice's friend is #{alice.get(:friend)}"
#get
returns nil
if no matching predicate exists.
#get_all
#
puts "Alice's friends are #{alice.get_all(:friend).join(", ")}"
#fetch
#
puts "Alice's friend is #{alice.fetch(:friend)}"
This has the same interface as Hash#fetch
: it accepts a default value or a block, and raises a KeyError
if no matching facts exist and no defaults are given.
#method_missing
and #respond_to?
#
The predicate needs to be a symbol for this to work, as is generally recommended.
puts "Alice's friend is #{alice.friend}" if alice.respond_to?(:friend)
This raises a NoMethodError
if no matching facts exist.