簡體   English   中英

如何定義一個類似於“ yield”的方法(我是說,自動捕獲塊)?

[英]How to define a method some how like the 'yield' ( I mean, automatically catch the block)?

如果我需要定義一個稱為“ yields”的方法,它將調用yiled 3次:


def yields
  3.times do
    yield
  end
end

然后,我將其用於其他方法:


def call_me_3_times
  yields
end

在控制台或irb中:


>> call_me_3_times { puts 'me'} # => Cause error
=>  LocalJumpError: no block given (yield)
 from (irb):32:in `yields'
    from (irb):35:in `call_me_3_times'

我希望你能閱讀我想要的東西;
以及如何使“收益”自動捕獲給定的區塊?


我的意思是,當我們使用'yields'時,我們不需要將其傳遞給'&block',就像'yield'的用法一樣( 我們甚至不必將'&block'傳遞給'屈服',需要嗎? )。



就像是:

def call_me_3_times &block
  yields &block
end

我嘗試查看yield實施以查看是否可以重現其行為,但是我認為它是一個關鍵字,因此無法查看實現。

我嘗試使用block_given,並從ruby核心rdocs中查看實現,我發現block_given嗎? 是這樣實現的:

rb_f_block_given_p()
{
  if (ruby_frame->prev && ruby_frame->prev->iter == ITER_CUR && ruby_block)
    return Qtrue;
  return Qfalse;
}

如您所見,它是C,所以它的實現太底層了。 我們不能做同樣的事情。

如果block_given? 方法需要依靠C實現僅檢查是否已給出一個塊,我看不到如何獲得該塊並在ruby代碼中調用它。

所以我認為沒有辦法做你想做的事。

您需要給yields方法一個塊,如果沒有塊,請避免yield

如果沒有塊,則沒有產量:

def yields
  3.times do
    yield if block_given?
  end
end

將塊傳遞給yields方法

def call_me_3_times
  yields { puts 'hello' }
end

可以使用此博客文章http://weblog.raganwald.com/2008/06/what-does-do-when-used-as-unary.html中描述的技術來創建解決方案

def call_me_three_times
  yields &(Proc.new) if block_given?
end

當您將方法定義為def some_method(&block) ruby會期望您將一個塊傳遞給該方法。 它將將該塊轉換為Proc並將其存儲在block變量中。

如果在Proc對象前加上&前綴,則會將其轉換為塊。

如果您在方法中調用Proc.new而不為其提供塊,則它將從傳遞給它的塊中創建一個Proc。

一些測試結果如下

def yields
  puts "Tripling"
  3.times do 
    yield 
  end
end

def call_me_three_times 
  yields &(Proc.new) if block_given?
end

x="Foo"
call_me_three_times { puts x }
x="Bar"
call_me_three_times { puts x }
call_me_three_times

輸出量

Tripling
Foo
Foo
Foo
Tripling
Bar
Bar
Bar

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM