Ruby 块(需要解决方案)

Ruby blocks (need a solution)

问题是这样的:

Write in the class Range method todown behaves like this (use block_given? and yield functions):

(3..5).todown {|i| print "hi#{i} "} #prints hi5 hi4 hi3

(2...7).todown #prints 65432

经过至少一个小时的谷歌搜索,我仍然无法解决这个问题。我已经做到了这一点:

class Range
 def todown
     to_a.reverse.each do |i|
       yield(i)
   end
  end
 end

我不知道在哪里添加 (2..7).todown 行以获得所需的结果。

你可以使用类似这样的东西,通过使用 to_a 将范围变成一个数组,然后使用 reverse_each 在给定块时产生。

否则,我们将打印它。

class Range
  def todown
    reverse_each do |v| 
       yield v if block_given? 
       print v unless block_given?
    end
  end
end

你有没有尝试过类似的东西:

(3..5).reverse_each { |i| print "hi#{i} " }

您还可以通过以下方式修补 Range:

class Range
  def todown
    reverse_each do |i|
      if block_given?
        yield i
      else
        print i
      end
    end
  end
end

这样你就可以做到:

(3..5).todown { |i| print "hi#{i} " }

编辑:

我知道这个问题只是一个练习,但是在修改 Ruby 的核心 classes 时应该非常小心。 Here 是讨论 "money-patching" 的危险以及可将风险降至最低或在核心 class 补丁爆炸时使调试更容易的步骤的众多文章之一。

我们现在有一个(有点争议的)替代方案,叫做 "Refinements"。 Refinements 是对 v2.0 的实验性补充。然后在 v2.1 中对其进行了修改并永久保留。这是它在这里的工作方式。

首先,我们refine一个模块中的class:

module M  
  refine Range do
    def todown
      reverse_each do |i|
        case block_given?
        when true then yield(i)
        else print i
        end
      end
      puts
    end
  end
end

让我们试试看:

(2...7).todown
  #-> NoMethodError: undefined method `todown' for 2...7:Range

糟糕!我们已经创建了优化,但还没有激活它。为此,我们使用关键字 using:

using M
(2...7).todown
  #-> 65432
(3..5).todown { |i| print "hi#{i} " }
  #-> hi5 hi4 hi3 

我在细化中添加了方法,但您可以添加、修改、重命名或删除现有实例或 class 方法,添加常量等。

最后一件事:改进似乎在 IRB 中不起作用。 :tidE]

你可以这样做:

class Range
  def todown
    f,l = first,last
    l -= 1 if exclude_end?
    if block_given?
      while l >= f
        yield(l)
        l -= 1
      end
    else
      s = ''
      while l >= f
        s << l.to_s
        l -= 1
      end
      puts(s)
    end
  end
end

(2...7).todown
  #-> 65432
(3..5).todown { |i| print "hi#{i} " }
  #-> hi5 hi4 hi3 

虽然有点长,但您会看到大多数 Ruby 的内置方法(用 Ruby 编写,而不是用 C 编写)都是以类似的方式构造的,尽可能减少对其他 classes.

方法的依赖