2015-07-21 2 views
3

Я пытаюсь создать класс в Ruby, который проверяет тип и вызывает ошибку, если находит что-то, чего он не ожидал. Вот что у меня до сих пор:Ruby: Получение имени переменной

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]) 

Мой вопрос: что это лучший способ, чтобы вернуть имя переменной, которая не была определенного типа? Я пытаюсь сделать это в этой линии здесь:

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

Но, похоже, связывание не может быть пропущена через в сферу? В идеале мое возвращение было бы «Ожидаемое испытание_var должно быть типом: String»

Любые мысли или идеи?

+0

Или если вам нужна дополнительная информация «Ожидаемый # {variable.inspect} для типа: # {type}" –

+0

Tho se не даст вам имя переменной, а скорее строковое представление этой переменной. ОП запрашивает имя. –

ответ

3

Это не сработает.

Нет надежного способа получить имя переменной, которой назначен объект. Вот надуманный пример:

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

var = 123 
check(var) 

Какое сообщение об ошибке в этом случае?

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

Кроме того, вы можете легко создавать объекты, которые не отнесены к переменной:

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

Лучшее сообщение об ошибке будет:

#=> Expected 123 to be type: String 

т.е. просто использовать variable.inspect

+1

Другим подходом было бы передать символы между связыванием в этот метод, например: 'LibHelper :: Base.check_type (self.send (: binding), [: test_var], [String])'. – mudasobwa

+0

@mudasobwa да, но это ограничило бы метод проверки локальных переменных в текущей области. – Stefan

+0

Да, это зависит от того, что действительно хотел ОП. Во всяком случае, я просто упомянул о другой возможности. – mudasobwa

Смежные вопросы