Ruby块(需要解决方案)

时间:2015-03-31 03:43:18

标签: ruby yield

问题如下:

  

在类Range中写入todown的行为如下(使用block_given?和yield函数):

     

(3..5).todown {| i |打印“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行来获取所需的结果。

3 个答案:

答案 0 :(得分:2)

你有没有试过像:

(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} " }

答案 1 :(得分:1)

你可以使用这样的东西,通过利用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

答案 2 :(得分:0)

修改

我意识到问题只是一个练习,但是在修改Ruby的核心类时应该非常小心。 Here是讨论“货币修补”危险的许多文章之一,以及可能采取的措施,以最大限度地降低风险,或在核心类修补程序爆炸时使调试更容易。

我们现在有一个(有点争议的)替代品叫做“Refinements”。 Refinements是v2.0的实验性补充。它随后被修改并在v2.1中成为永久性的。这是它在这里的工作方式。

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

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 

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

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

你可以这样做:

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语言编写)都以类似的方式构造,以尽可能减少对其他类中方法的依赖。