2011-09-19 38 views
1

我有一个方法可以接受一个块,让我们把它叫做外层。它又调用一个接受另一个块的方法,称它为内部。在Ruby中访问传递的块

我想要发生的是外层调用内层,传递一个新的块调用第一个块。

这里有一个具体的例子:

class Array 
    def delete_if_index 
    self.each_with_index { |element, i| ** A function that removes the element from the array if the block passed to delete_if_index is true } 
    end 
end 

['a','b','c','d'].delete_if_index { |i| i.even? } 
    => ['b','d'] 

传递给delete_if_index块被传递到each_with_index块调用。

这是可能的,在Ruby中,更广泛地说,我们有多少访问接收它的函数内的块?

+0

我想我知道你的意思,但是如果你能显示出一些你想做的事情的伪代码可能会有所帮助。当你谈论接收块时,你的意思是像Ruby语言结构中的块一样,还是你的意思是闭包? – glenatron

+0

您可以将块包装在另一个块中。那对你有用吗? –

+0

感谢您的评论,我添加了一个具体的例子。我怀疑我可能会对此有点错误,但知道这件事仍然很有趣。 – superluminary

回答

4

可以在另一块裹块:

def outer(&block) 
    if some_condition_is_true 
    wrapper = lambda { 
     p 'Do something crazy in this wrapper' 
     block.call # original block 
    } 
    inner(&wrapper) 
    else 
    inner(&passed_block) 
    end 
end 

def inner(&block) 
    p 'inner called' 
    yield 
end 

outer do 
    p 'inside block' 
    sleep 1 
end 

我想说开放现有的块并改变其内容的做法有误TM,也许延续传递,将有助于在这里?我也会小心翼翼地绕过带有副作用的街区;我尝试保持lambdas确定性,并执行像删除方法体中的东西。在复杂的应用程序中,这可能会使调试变得更容易。

1

也许例子不好选择,但你的具体的例子是一样的:

[1,2,3,4].reject &:even? 

开放和修改块给我的印象码味。以难以使副作用明显的方式编写它会很困难。

考虑到你的例子,我认为高阶函数的组合将做你想要解决的问题。

更新:这是不一样的,正如评论中指出的那样。 [1,2,3,4].reject(&:even?)查看内容,而不是索引(并且返回问题中的[1,3],而不是[2,4])。下面的例子相当于原始的例子,但不会变化很多。

[1,2,3,4].each_with_index.reject {|element, index| index.even? }.map(&:first) 
+0

这是一个不好的例子。假设数组不包含数字:['a','b','c','d','e','f']应返回['b','d','f']。 – superluminary

+0

也许不是最好的oneliner,但是:['a','b','c','d','e','f']。each_with_index.reject {| letter,i | (&:first) –

+0

我认为这只适用于1.8.7及更高版本。 #each_with_index返回一个枚举器,如果它没有被调用。 –

0

所以这里是我自己的问题的解决方案。传入的块将隐式转换为可以通过参数语法接收的proc。然后,PROC任何嵌套块的闭合内部存在的,因为它被分配给的范围的局部变量,并且可以通过它可以称为:

class Array 
    def delete_if_index(&proc) 
    ary = [] 
    self.each_with_index { |a, i| ary << self[i] unless proc.call(i) } 
    ary 
    end 
end 

[0,1,2,3,4,5,6,7,8,9,10].delete_if_index {|index| index.even?} 

    => [1, 3, 5, 7, 9] 

在这里,块被转换成一个PROC,并分配给变量proc,然后在传递给each_with_index的块中可用。