你如何重构像这样的长 ruby 方法签名
How do you refactor long ruby method signatures like this one
如何清理这个 ruby 方法签名?
def card(title: nil, textured: nil, threed: true,
borderless: false, bodyless: false, title_classes: ['card-header'])
问题是我收到 linting/rubocop 警告:
Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]
我的方法有这么多关键字参数的原因是,
我使该方法非常灵活。它很强大。
尝试使用这些属性创建案例 class/data class。
class CardProperties
attr_accessor :title, :textured, :threed, :borderless, :bodyless, :title_classes
end
创建一个新的CardProperties
并将其传递给卡片方法:
card_properties = CardProperties.new
card_properties.title = ''
....
card(card_properties)
嗯,理论上您可以使用关键字参数和 Hash#fetch
来处理默认值:
def card(**params)
title = params.fetch(:title, nil)
textured = params.fetch(:textured, nil)
threed = params.fetch(:threed, true)
borderless = params.fetch(:borderless, false)
bodyless = params.fetch(:bodyless, false)
title_classes = params.fetch(:title_classes, ['card-header'])
...
但我个人的建议是让 rubocop 闭嘴:
# rubocop:disable Metrics/ParameterLists
def card(...)
...
end
# rubocop:enable Metrics/ParameterLists
做rails做的事
# Creates a number field.
#
# ==== Options
# * <tt>:min</tt> - The minimum acceptable value.
# * <tt>:max</tt> - The maximum acceptable value.
# * <tt>:in</tt> - A range specifying the <tt>:min</tt> and
# <tt>:max</tt> values.
# * <tt>:within</tt> - Same as <tt>:in</tt>.
# * <tt>:step</tt> - The acceptable value granularity.
# * Otherwise accepts the same options as text_field_tag.
#
# ==== Examples
# number_field_tag 'quantity'
# # => <input id="quantity" name="quantity" type="number" />
#
# number_field_tag 'quantity', '1'
# # => <input id="quantity" name="quantity" type="number" value="1" />
#
# number_field_tag 'quantity', nil, class: 'special_input'
# # => <input class="special_input" id="quantity" name="quantity" type="number" />
#
# number_field_tag 'quantity', nil, min: 1
# # => <input id="quantity" name="quantity" min="1" type="number" />
#
# number_field_tag 'quantity', nil, max: 9
# # => <input id="quantity" name="quantity" max="9" type="number" />
#
# number_field_tag 'quantity', nil, in: 1...10
# # => <input id="quantity" name="quantity" min="1" max="9" type="number" />
#
# number_field_tag 'quantity', nil, within: 1...10
# # => <input id="quantity" name="quantity" min="1" max="9" type="number" />
#
# number_field_tag 'quantity', nil, min: 1, max: 10
# # => <input id="quantity" name="quantity" min="1" max="10" type="number" />
#
# number_field_tag 'quantity', nil, min: 1, max: 10, step: 2
# # => <input id="quantity" name="quantity" min="1" max="10" step="2" type="number" />
#
# number_field_tag 'quantity', '1', class: 'special_input', disabled: true
# # => <input disabled="disabled" class="special_input" id="quantity" name="quantity" type="number" value="1" />
def number_field_tag(name, value = nil, options = {})
options = options.stringify_keys
options["type"] ||= "number"
if range = options.delete("in") || options.delete("within")
options.update("min" => range.min, "max" => range.max)
end
text_field_tag(name, value, options)
end
如何清理这个 ruby 方法签名?
def card(title: nil, textured: nil, threed: true,
borderless: false, bodyless: false, title_classes: ['card-header'])
问题是我收到 linting/rubocop 警告:
Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [6/5]
我的方法有这么多关键字参数的原因是, 我使该方法非常灵活。它很强大。
尝试使用这些属性创建案例 class/data class。
class CardProperties
attr_accessor :title, :textured, :threed, :borderless, :bodyless, :title_classes
end
创建一个新的CardProperties
并将其传递给卡片方法:
card_properties = CardProperties.new
card_properties.title = ''
....
card(card_properties)
嗯,理论上您可以使用关键字参数和 Hash#fetch
来处理默认值:
def card(**params)
title = params.fetch(:title, nil)
textured = params.fetch(:textured, nil)
threed = params.fetch(:threed, true)
borderless = params.fetch(:borderless, false)
bodyless = params.fetch(:bodyless, false)
title_classes = params.fetch(:title_classes, ['card-header'])
...
但我个人的建议是让 rubocop 闭嘴:
# rubocop:disable Metrics/ParameterLists
def card(...)
...
end
# rubocop:enable Metrics/ParameterLists
做rails做的事
# Creates a number field.
#
# ==== Options
# * <tt>:min</tt> - The minimum acceptable value.
# * <tt>:max</tt> - The maximum acceptable value.
# * <tt>:in</tt> - A range specifying the <tt>:min</tt> and
# <tt>:max</tt> values.
# * <tt>:within</tt> - Same as <tt>:in</tt>.
# * <tt>:step</tt> - The acceptable value granularity.
# * Otherwise accepts the same options as text_field_tag.
#
# ==== Examples
# number_field_tag 'quantity'
# # => <input id="quantity" name="quantity" type="number" />
#
# number_field_tag 'quantity', '1'
# # => <input id="quantity" name="quantity" type="number" value="1" />
#
# number_field_tag 'quantity', nil, class: 'special_input'
# # => <input class="special_input" id="quantity" name="quantity" type="number" />
#
# number_field_tag 'quantity', nil, min: 1
# # => <input id="quantity" name="quantity" min="1" type="number" />
#
# number_field_tag 'quantity', nil, max: 9
# # => <input id="quantity" name="quantity" max="9" type="number" />
#
# number_field_tag 'quantity', nil, in: 1...10
# # => <input id="quantity" name="quantity" min="1" max="9" type="number" />
#
# number_field_tag 'quantity', nil, within: 1...10
# # => <input id="quantity" name="quantity" min="1" max="9" type="number" />
#
# number_field_tag 'quantity', nil, min: 1, max: 10
# # => <input id="quantity" name="quantity" min="1" max="10" type="number" />
#
# number_field_tag 'quantity', nil, min: 1, max: 10, step: 2
# # => <input id="quantity" name="quantity" min="1" max="10" step="2" type="number" />
#
# number_field_tag 'quantity', '1', class: 'special_input', disabled: true
# # => <input disabled="disabled" class="special_input" id="quantity" name="quantity" type="number" value="1" />
def number_field_tag(name, value = nil, options = {})
options = options.stringify_keys
options["type"] ||= "number"
if range = options.delete("in") || options.delete("within")
options.update("min" => range.min, "max" => range.max)
end
text_field_tag(name, value, options)
end