I have a method that takes a condition and item, from an array of conditions and array of items, where any number of conditions are checked against any number of items. Conditions and Items are Hashes Basically, for the condition and item fed to the method, find out what attribute of the item the condition needs to check against. The list is actually longer, and looking into making this better (seems like this could be more concise and perhaps more rubyesque) nothing else has worked(yet), so I’d like some input on how you might refactor this:
def check_condition(condition, item)
case condition.attribute
when :author
i = item.author.name;
when :title
i = item.title
when :body
i = item.body
when :domain
i = URI(item.url).host
when :account_age
i = item.author.author_age
end
@logger.info "#{i} to be checked if #{condition.query} #{condition.attribute}"
test_condition(condition, item, i)
end
EDIT:
Just to make clearer, items and conditions are Hashes (Hashie::Mash to be exact) where conditions are in general constructed from a config file that might be something like:
[submitted_link, account_age, is_less_than, 30, remove]
that ends up something like:
{subject: submitted_link, attribute: account_age, query: is_less_than, what: 30 action:remove}
And you can see what is going on as a whole here if you are so inclined: https://github.com/blueblank/reddit_modbot/blob/master/lib/modbot/modbot_check.rb
EDIT2:
The reality of the solution was to somewhat regularize my variable terminology for condition and item so this could be reduced to 1 line
i = item.send(condition.attribute)
no mess, minimal impact
One alternative might involve defining
check_conditionas a method ofitem.class. So instead of……you might have something like…
Then, if you don’t like the big case, you could create a hash with values that are proc objects, keyed by
:author,:title,etc.However, once you do that, you might then want to take a third step, which would be to change all those object attributes to values in a
Hashin the first place … maybe …