Skip to content

Instantly share code, notes, and snippets.

@jeremycw
Last active May 9, 2022 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeremycw/33cdd7bd801c04a0aa4eab7ac6829cb2 to your computer and use it in GitHub Desktop.
Save jeremycw/33cdd7bd801c04a0aa4eab7ac6829cb2 to your computer and use it in GitHub Desktop.
Basic expression interpreter
class Interpreter
attr_reader :user
def initialize(user)
@user = user
end
def evaluate(expression)
return send(*expression.map { |arg| arg.is_a?(Array) ? evaluate(arg) : arg })
end
def and(*args)
args.all?
end
def or(*args)
args.any?
end
def older_than(age)
user.age > age
end
def lives_in_state(state)
user.state == state
end
def visible_until(timestamp)
Time.now < Time.parse(timestamp)
end
# Add any arbitrary conditional methods here as needed to extend your
# expression language. You'd need to add message as an attribute for this one.
#
# def unseen
# !SeenMessage.where(user_id: user.id, message_id: message.id).exists?
# end
end
user = OpenStruct.new
user.name = 'bob'
user.age = 23
user.state = 'WA'
interpreter = Interpreter.new(user)
interpreter.evaluate(["and", ["older_than", 18], ["lives_in_state", "WA"]]) # => true
interpreter.evaluate(["and", ["older_than", 18], ["lives_in_state", "CA"]]) # => false
interpreter.evaluate(["or", ["older_than", 24], ["lives_in_state", "WA"]]) # => true
interpreter.evaluate(["or", ["older_than", 24], ["lives_in_state", "CA"]]) # => false
# Add a date after which the message will no longer show
interpreter.evaluate(["and", ["older_than", 18], ["lives_in_state", "WA"], ["visible_until", "2022-05-15"]])
# With just a few building blocks you can start evaluating some complex expressions
# Anyone > age 18 in washington or anyone in california
interpreter.evaluate(["or", ["and", ["older_than", 18], ["lives_in_state", "WA"]], ["lives_in_state", "CA"]])
# Each message would be given an expression
# messages_to_display = messages.select { |msg| interpreter.evaluate(msg.expression) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment