所以,我正在浏览The Odin Project's Ruby Path,在其中一个项目中,我们必须将一些Enum
函数重写为它们的基本功能。问题是,我想尝试超越并重新创建那些函数,尽可能接近原始函数,这就带来了Enum#inject
。
我使用以下代码重新创建了它(在Enumerable
模块中)
def my_inject(initial = first, sym = nil)
memo = initial
enum = to_a
if block_given?
enum.my_each_with_index do |el, idx|
next if memo == first && idx.zero?
memo = yield memo, el
end
else
block = sym.to_proc
enum.my_each_with_index do |el, idx|
next if memo == first && idx.zero?
memo = block.call memo, el
end
end
memo
end
(my_each_with_index
是each_with_index
的自定义版本,其工作方式应该如此)
这个版本 * 几乎 * 工作正常。问题是只有当我只用Symbol
作为参数调用它时,就像在((5..10).my_inject(:+))
中一样,导致它抛出'my_inject': undefined method 'to_proc' for nil:NilClass (NoMethodError)
。
我猜这是因为符号作为initial
值传递,作为函数的第一个参数。
我想尝试写一堆检查(比如检查函数是否只有一个参数,并且该参数是一个符号),但我想知道是否有更简单、更干净的方法来完成。
(请记住,我学习代码的时间不超过6个月,所以我是一个非常非常非常的绿色)。
谢谢你的帮助!
1条答案
按热度按时间osh3o9ms1#
内置 的
inject
是 非常 多态 的 , 所以 在 尝试 从头 开始 实现 它 之前 ( 不 看 源 代码 ) , 我们 需要 研究 它 在 不同 情况 下 的 行为 。 我 跳过 了 你 已经 知道 的 事情 ( 比如 如果 没有 显 式 提供 , 使用 第 一 个 元素 作为 初始 值 等 ) , 除 此 之外 :中 的 每 一 个
记住 这些 信息 后 , 我们 可以 编写 如下 代码 :
格式
忍耐 一下 , 我们 就 快 到 了 : ) 让 我们 来 看看 它 是 如何 嘎嘎 叫 的 :
格式
所以 , 几乎 是 一样 的 。 可能 还有 一些 其他 的 边缘 情况 , 我 的 实现 不能 满足 , 但 我 把 它们 留给 你 : )