2012-01-31 50 views
3

我是Ruby的新手,我该如何做这样的事情?在C#中,我会写Ruby的等价LINQ ToList()

my_block().ToList() 

它会工作。

我想象这个功能

def my_block 
    yield 1 
    yield 2 
    yield 3 
end 

my_block.to_enum().map {|a| a} 

这给了我这个错误:

test.rb:2:in `my_block': no block given (yield) (LocalJumpError) 
    from test.rb:7:in `<main>' 

,这是什么行为,正确的咒语?

回答

5

为您的代码正确的语法是:

to_enum(:my_block).to_a # => [1,2,3] 

Object#to_enum愿与方法名作为参数符号:

to_enum(method = :each, *args)
enum_for(method = :each, *args)

Creates a new Enumerator which will enumerate by on calling method on obj.

等效为C#ToList()Enumerable#to_a

to_a → array
entries → array

Returns an array containing the items in enum.

+0

很酷,我不知道。 – 2012-01-31 16:50:29

1

你可以改变你的功能,所以它返回一个枚举。下面是如何会看一个例子:

def foo 
    Enumerator.new do |y| 
    y << 1 
    y << 2 
    y << 3 
    end 
end 

p foo  # => <Enumerator: #<Enumerator::Generator:0x1df7f00>:each> 
p foo.to_a # => [1, 2, 3] 
p foo.map { |x| x + 1 } # => [2, 3, 4] 

然后你可以使用任何的可枚举模块中的方法就可以了:

http://ruby-doc.org/core-1.9.3/Enumerable.html

标准库很多红宝石功能如果它们在被调用时没有通过一个块,它将返回一个枚举值,但是如果它们通过了一个块,它们将产生值给块。你也可以这样做。

+0

小修正,ruby 1.9中的这些函数将返回[Enumerator](http://www.ruby-doc.org/core-1.9.3/Enumerator.html),而不是Enumerable,因为您可能错误输入了答案。枚举器包含Enumerable模块。 – 2012-01-31 17:02:03

+0

是的。该函数返回的对象是一个Enumerator,它也是一个Enumerable。 'foo.is_a?(Enumerable)'返回true。对于多重继承,我认为可以说一个对象是多重事物。我并不特别在乎函数是否返回一个Enumerator,我只关心它是否返回一个Enumerable,因为它决定了我是否可以像'collect'和'select'一样使用所有有用的方法。 – 2012-01-31 17:12:10

+0

谢谢大卫,我不知道这种方法。我可以看到它有助于构建更多行为良好的库 Alex的方法更加简洁,满足我的需求,并且不需要我更改调用函数,只需调用者即可。这就是说,你的答案仍然是正确的。但我想我只能有一个答案... – Doug 2012-01-31 17:48:31