def compare_by(mode, *args)
if args.count == 2
values = args[0]
expression = args[1]
if get_type(values) == ARRAY_TYPE && get_type(expression) == EXPRESSION_TYPE
type = get_type(expression.eval(values.first))
if type != NUMBER_TYPE && type != STRING_TYPE
msg = "function #{mode}() expects values to be strings or numbers"
raise Errors::InvalidTypeError, msg
end
values.send(mode) do |entry|
value = expression.eval(entry)
value_type = get_type(value)
if value_type != type
msg = "function #{mode}() encountered a type mismatch in "
msg << "sequence: #{type}, #{value_type}"
raise Errors::InvalidTypeError, msg
end
value
end
else
msg = "function #{mode}() expects an array and an expression"
raise Errors::InvalidTypeError, msg
end
else
msg = "function #{mode}() expects two arguments"
raise Errors::InvalidArityError, msg
end
end