3

I'm trying to create a class in Ruby that checks for a type and raises an error if it finds something it didn't expect. Here's what I've got so far:

module LibHelper
  class Base
    def self.check_type(variables, types)
      raise "Expected variables to be an array" unless variables.is_a?(Array)
      raise "Expected types to be an array" unless types.is_a?(Array)
      raise "Variable array and type array aren't same length" unless variables.length == types.length
      variables.zip(types).each do |variable, type|
        raise "Expected parameters in variables array to be symbols" unless variable.is_a?(Symbol)
        raise "Expected #{eval(variable.to_s, binding)} to be type: #{type}" unless variable.is_a?(type)
      end
    end

    def self.valid_type?(type)
      valid_types = [String, Fixnum, NilClass, Hash, Symbol]
      raise "Expected type to be String, Fixnum, NilClass, Hash, or Symbol got #{type}" unless valid_types.include?(type)
    end
  end
end

test_var = 'just_a_test_string'
LibHelper::Base.check_type([test_var], [String])

My question is what is the best way to return the name of the variable that wasn't a certain type? I'm trying to do so in this line here:

raise "Expected #{eval(variable.to_s, binding)} to be type: #{type}" unless variable.is_a?(type)

But it seems like binding might not be passed through in the scope? Ideally my return would be 'Expected test_var to be type: String'

Any thoughts or ideas?

2
  • Or if you need more info "Expected #{variable.inspect} to be type: #{type}" Commented Jul 21, 2015 at 13:40
  • Those won't give you the name of the variable, rather the string representation of that variable. OP is asking for the name. Commented Jul 21, 2015 at 13:53

1 Answer 1

3

It's not going to work.

There's no reliable way to retrieve the variable name an object is assigned to. Here's a contrived example:

def check_string(foo)
  bar = foo
  LibHelper::Base.check_type([bar], [String])
end

var = 123
check(var)

What's the correct error message in this case?

#=> Expected var to be type: String
#=> Expected foo to be type: String
#=> Expected bar to be type: String

Furthermore you can easily create objects that are not assigned to a variable:

LibHelper::Base.check_type([123], [String])

A better error message would be:

#=> Expected 123 to be type: String

i.e. just use variable.inspect

Sign up to request clarification or add additional context in comments.

4 Comments

Another approach would be to pass symbols among binding into this method, like: LibHelper::Base.check_type(self.send(:binding), [:test_var], [String]).
@mudasobwa yeah, but that would limit the method to check local variables within the current scope.
Yes, it depends on what OP actually wanted. Anyway, I was just mentioning another possibility.
Thanks Stefan, it'd be cool if I could put out value and var name, but value will work too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.