Каковы варианты хэшей?
Будет ли кто-нибудь объяснять хэши вариантов? Я работаю через рубиновый курс от testfirst.org. Упражнение 10 (temperature_object) требует знания хэшей опций.
Ответы
Ответ 1
Параметр hash - это хорошая концепция, включенная функцией рубинового анализатора. Скажем, у вас есть метод с некоторыми необходимыми аргументами. Также вы можете передать некоторые необязательные аргументы. Со временем вы можете добавить дополнительные аргументы или удалить старые. Чтобы сохранить декларацию метода чистой и стабильной, вы можете передать все эти необязательные аргументы в хеш. Такой метод будет выглядеть следующим образом:
def foo(arg1, arg2, opts = {})
opts.to_s # just return a string value of opts
end
Таким образом, он имеет два обязательных значения и последний аргумент со значением по умолчанию для хэша. Если у вас нет дополнительных аргументов для передачи, вы вызываете это следующим образом:
foo(1, 2) # => "{}"
Если у вас есть что-то необязательное, вы вызываете его так:
foo(1, 2, {truncate: true, redirect_to: '/'}) # => "{:truncate=>true, :redirect_to=>\"/\"}"
Этот код настолько идиоматичен для ruby, что его парсер фактически позволяет вам опустить фигурные скобки, передавая хэш как последний аргумент методу:
foo(1, 2, truncate: true, redirect_to: '/') # => "{:truncate=>true, :redirect_to=>\"/\"}"
Если вы используете рельсы, например, вы увидите везде хэши параметров. Здесь я открыл в своем приложении только случайный контроллер:
class ProductsController < ApplicationController
before_filter :prepare_search_params, only: :index
# ^^^^^^^^^^ options hash here
Итак, короче: options hash - это аргумент метода, который находится последним и имеет значение по умолчанию {}
. И вы обычно передаете ему хеши (отсюда и название).
Ответ 2
Хэши параметров часто используются, когда необходимо передавать необязательные аргументы методу.
Например, если метод имеет один-два необязательных аргумента, вы можете написать
def method(arg1, arg2 = nil, arg3 = nil)
...
end
Но если у вас больше опциональных аргументов, то становится уродливым, чтобы каждый раз назначать их нулю.
Здесь идет хэш параметров, который позволяет вам писать
def method(arg1, options={})
@arg1 = arg1
@arg2 = options[:arg2]
....
@arg15 = options[:arg15]
end
Ответ 3
Хэш хешей относится к соглашению о передаче опций методам с использованием хэша ({}
), например
my_func(arg1, arg2, {:opt1 => 'foo', :opt2 => 'bar'})
Соглашение заключается в том, что хэш параметров является последним аргументом, чтобы его можно было сделать необязательным. Например.
def my_func(argument1, argument2, options = {})
...
end
Таким образом, хэш настроек не является чем-то особенным. Это просто дополнительный аргумент, который является хешем. Хэши параметров настолько удобны и распространены, что интерпретатор также позволяет вам оставить фигурные скобки (это одна из них "особая" часть)
my_func(arg1, arg2, :opt1 => 'foo', :opt2 => 'bar')
В сочетании с ярлыком клавиш хеша символа Ruby и дополнительными круглыми скобками это может выглядеть очень чисто:
my_func arg1, arg2, opt1: 'foo', opt2: 'bar'
Ответ 4
Reverse Merge - лучший способ реализовать хэши опций в ruby /rails:
def set_state_application(options_hash)
options_hash.reverse_merge!(send_email: true, other_default_val: 'a') #will set defaults
self.update_column(:status_id, VendorEnums::VendorStatus::APPLICATION)
VendorMailer.email_application(self) if options_hash[:send_email]
save_state
end
Ответ 5
Поскольку все эти ответы верны, ruby 2 улучшил поддержку аргументов ключевых слов.
Вы можете определить свой метод с параметрами hash по умолчанию как *args
и избавиться от options = {}
.
def foo(bar: 'initial')
puts bar
end
foo # => 'initial'
foo(bar: 'final') # => 'final'
Необходимые аргументы: вам нужен двоеточие после ключа (также вам нужно ruby 2.1)
def foo(bar:)
puts bar
end
foo # => ArgumentError: missing keyword: bar
foo(bar: 'baz') # => 'baz'
Дополнительные аргументы, вы можете установить значение по умолчанию nil
def foo(bar: nil, baz: 'aaa')
puts "#{bar}:#{baz}"
end
foo # => ':aaa'
foo(baz: 'zab') # => ':zab'
foo(bar: 'rab', baz: 'zab') # => 'rab:zab'
foo(bin: 'bin') # => ArgumentError: unknown keyword: bin
Также вы можете использовать стандартные позиционные args с этой новой нотой параметров хэша. Более подробную информацию вы найдете в этом блоге и на официальном документация.
Бонус: рефакторинг прост, потому что вы можете избавиться от хэш-настроек вашего метода без изменения его звонков. Но... это не совсем так, если у вас есть вызов с неожиданной опцией, вы получите ArgumentError: unknown keyword: invalid_arg
.