Подтвердить что ты не робот

Как символы используются для идентификации аргументов в методах 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")

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

4b9b3361

Ответ 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, у меня были подобные путаницы, и мне ответ, подобный следующему, имел бы больше смысла

Аргументы метода - это локальные переменные, заполненные переданными значениями.

Вы не можете использовать символы как Аргументы сами по себе, поскольку вы не можете изменить значение символа.