Last active
May 9, 2022 19:59
-
-
Save jeremycw/33cdd7bd801c04a0aa4eab7ac6829cb2 to your computer and use it in GitHub Desktop.
Basic expression interpreter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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