Использование символов в качестве аргументов для методов ruby - PullRequest
14 голосов
/ 05 ноября 2011

Я изучаю рельсы и возвращаюсь к ruby, чтобы понять, как методы в рельсах (и ruby ​​действительно работают).Когда я вижу вызовы методов вроде:

validates validates :first_name, :presence => true

, я запутываюсь.Как вы пишете методы в ruby, которые принимают символы или хэши.Исходный код для метода validates тоже сбивает с толку.Может кто-нибудь упростить эту тему использования символов в качестве аргументов в классе ruby ​​и методах экземпляров для меня?

ОБНОВЛЕНИЕ:

Хороший @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")

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

Ответы [ 5 ]

22 голосов
/ 05 ноября 2011

Символы и хэши являются значениями, как и любые другие, и могут передаваться как любой другой тип значения.

Напомним, что модели 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')

Это дает преимущество, заключающееся в том, что хеш не заключают в фигурные скобки {}, если тольковам необходимо устранить неоднозначность параметров (и при анализе пропусков паренов также возникает проблема с блоком).

Аналогично:

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}'

Оттуда вы можете начать видеть, как такие вещи работают.

9 голосов
/ 30 сентября 2013

Я думал, что добавлю обновление для 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 действительно изменяется при вызове функции.

5 голосов
/ 05 ноября 2011

В 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 является символом, используемым в качестве хэш-ключа - любой тип может использоваться в качестве хэш-ключа, но символы являются распространенным выбором, поскольку они являются неизменяемыми значениями.

2 голосов
/ 30 марта 2012

Я думаю, что во всех ответах пропущен вопрос;и тот факт, что его спрашивает кто-то, кто, я полагаю, не совсем понимает, что такое символ?

Как новичок в Ruby, у меня возникли аналогичные недоразумения, и для меня ответ вроде следующего имел бы больше смысла1003 *

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

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

2 голосов
/ 05 ноября 2011

Символы не ограничиваются хэшами.Они являются идентификаторами, без дополнительного места для хранения строки.Это просто способ сказать «это ...»):

def validates(column, options)
   puts column.to_s
   if options[:presence]
     puts "Found a presence option"
   end
 end

Обратите внимание, что первый символ является собственным параметром, а остальное - хеш.

...