如何使 Ruby 方法显示他们期望的类型

How to make Ruby methods show what types they expect

使用 Ruby 方法名称表达意图的最佳做法是什么?

例如,使用以下内容:

class Formula
  attr_accessor :steps

  def find_step(key)
    @steps.find {|s| s.name == key }
  end

end

和:

class Step
  attr_accessor :name
end

Formula#find_step 方法需要一个 Symbol 但它可以很容易地接受一个 Step 类型并检查名称是否匹配。我可以重命名方法 find_step_by_name 但仍然不清楚 name 是什么。它是字符串还是符号?还是与 Step 对象上的名称匹配?

编辑:标记为可能与 Does Ruby support type-hinting? 重复 我不是问可不可以,我是问命名的问题

我会争辩说 find_step_by_name 清楚地表明需要一个 name 而不是一个可能有名字的 step 。如果您不确定是否支持字符串或符号,则同时允许:

  def find_step_by_name(name)
    @steps.find { |s| s.name == name.to_s }
  end

在Ruby2.1之后,我认为下面的解决方案很好。

def find_by(name:)
  # and you can check if type of name is what you expect as you need.
  # But that is not duck-typingy.
end

我认为这个问题的最佳答案是参数名称的正确选择。如果您打算将一个符号传递到您的 find_by 方法中,为什么不这样做:

def find_by(symbol)
  @steps.find {|s| s.name == symbol }
end

但是,我认为这是最明确的选择:

def find_by_name(symbol)
  @steps.find {|s| s.name == symbol }
end

我不同意使用关键字来解决这个问题。它所做的只是改变将字符串或符号传递到方法中的方式。

def find_by(name:)
  puts name
end

find_by name: 'this'  # name has to be passed in via hash
find_by name: :that

def find_by(name)
  puts name
end

find_by 'this' # name is passed in directly
find_by :that

没有解决 'name' 不暗示传入的对象类型的问题。

我认为如果将多个参数传递给方法,关键字非常有用,因为它们使代码在使用时更具可读性。

def mass(width:, height:, density:)
  width * height * density
end

mass width: 3, height: 11, density: 0.5

这意味着您不必在每次使用 mass 方法定义来计算传入的内容时都使用它。它还消除了使参数顺序正确的必要性。这同样有效:

mass width: 3, density: 0.5, height: 11

但是对于具有单个参数的方法,我认为您只是通过使用关键字来增加复杂性。