Как символы используются для идентификации аргументов в методах ruby
Я изучаю рельсы и возвращаюсь к рубину, чтобы понять, как методы в рельсах (и рубин действительно работают). Когда я вижу вызовы методов типа:
validates validates :first_name, :presence => true
Я запутался. Как вы пишете методы в ruby, которые принимают символы или хеши. Исходный код для метода validates также запутан. Может ли кто-нибудь упростить эту тему использования символов в качестве аргументов в классе ruby и методах экземпляра для меня?
UPDATE:
Хороший @Dave! Но то, что я пробовал, было чем-то вроде:
def full_name (:first_name, :last_name)
@first_name = :first_name
@last_name = :last_name
p "#{@first_name} #{last_name}"
end
full_name("Breta", "Von Sustern")
Что явно вызывает ошибки. Я пытаюсь понять: почему такие символы передаются как аргументы неправильно, если символы похожи на любые другие значения?
Ответы
Ответ 1
Символы и хеши являются значениями, как и любые другие, и могут передаваться как любой другой тип значения.
Напомним, что модели ActiveRecord принимают хэш в качестве аргумента; он заканчивается похожим на это (это не так просто, но в конце концов та же идея):
class User
attr_accessor :fname, :lname
def initialize(args)
@fname = args[:fname] if args[:fname]
@lname = args[:lname] if args[:lname]
end
end
u = User.new(:fname => 'Joe', :lname => 'Hacker')
Это позволяет не помещать хеш в фигурные скобки {}
, если вам не нужно устранять неоднозначность параметров (а также проблема с парсингами блока, когда вы пропускаете parens).
Аналогично:
class TestItOut
attr_accessor :field_name, :validations
def initialize(field_name, validations)
@field_name = field_name
@validations = validations
end
def show_validations
puts "Validating field '#{field_name}' with:"
validations.each do |type, args|
puts " validator '#{type}' with args '#{args}'"
end
end
end
t = TestItOut.new(:name, presence: true, length: { min: 2, max: 10 })
t.show_validations
Выводится:
Validating field 'name' with:
validator 'presence' with args 'true'
validator 'length' with args '{min: 2, max: 10}'
Оттуда вы можете начать видеть, как это работает.
Ответ 2
Я думал, что добавлю обновление для Ruby 2+, так как это первый результат, который я нашел для "символов в качестве аргументов".
С Ruby 2.0.0 вы также можете использовать символы при определении метода. При вызове метода эти символы будут действовать почти так же, как и именованные необязательные параметры на других языках. См. Пример ниже:
def variable_symbol_method(arg, arg_two: "two", arg_three: "three")
[arg, arg_two, arg_three]
end
result = variable_symbol_method :custom_symbol, arg_three: "Modified symbol arg"
# result is now equal to:
[:custom_symbol, "two", "Modified symbol arg"]
Как показано в примере, мы опускаем arg_two:
при вызове метода и в теле метода мы все равно можем обращаться к нему как переменной arg_two
. Также обратите внимание, что переменная arg_three
действительно изменена вызовом функции.
Ответ 3
В Ruby, если вы вызываете метод с кучей пар name => value
в конце списка аргументов, они автоматически включаются в Hash
и передаются вашему методу в качестве последнего аргумента:
def foo(kwargs)
p kwargs
end
>> foo(:abc=>"def", 123=>456)
{:abc=>"def", 123=>456}
>> foo("cabbage")
"cabbage"
>> foo(:fluff)
:fluff
Нет ничего особенного в том, как вы пишете метод, как вы его называете. Было бы совершенно законно просто передавать обычный объект Hash в качестве параметра kwargs
. Этот синтаксический ярлык используется для реализации именованных параметров в API.
Символ Ruby - это просто значение, как и любое другое, поэтому в вашем примере :first_name
является просто регулярным позиционным аргументом. :presence
- это символ, используемый в качестве ключа Хэша. Любой тип может использоваться как хэш-ключ, но символы являются общим выбором, потому что они являются неизменяемыми значениями.
Ответ 4
Символы не ограничиваются хешами. Они являются идентификаторами без дополнительного пространства для хранения строки. Это просто способ сказать "это...."
Возможное определение функции для подтверждения проверки может быть (просто для упрощения, я не знаю, с моей точки зрения, что это на самом деле):
def validates(column, options)
puts column.to_s
if options[:presence]
puts "Found a presence option"
end
end
Обратите внимание, как первый символ является параметром, все из его собственных, а остальное - хешем.
Ответ 5
Я думаю, что все ответы упустили точку зрения; и тот факт, что его спрашивает кто-то, кто - я думаю, - не понятно, что такое символ?
Как новичок в Ruby, у меня были подобные путаницы, и мне ответ, подобный следующему, имел бы больше смысла
Аргументы метода - это локальные переменные, заполненные переданными значениями.
Вы не можете использовать символы как Аргументы сами по себе, поскольку вы не можете изменить значение символа.