rails on ruby,ruby on rails 之程式碼塊(二)
可呼叫物件
從底層看,使用程式碼塊分為兩步。第一步,將程式碼打包備用;第二步,呼叫程式碼塊(比如通過yield語句)執行程式碼。這種“打包程式碼,以後呼叫“的機制並不是程式碼塊的專利。在Ruby中,至少還有其他三種方法可以用來打包程式碼:
- 使用proc,proc是由塊轉換來的物件
- 使用lambda,它是proc的變種
Proc物件
儘管Ruby中絕大多數的東西都是物件,但是程式碼塊卻不是。為什麼要重點說明這個點呢?因為假如我們想儲存一個塊供以後執行,我們就需要一個物件。
為了解決這個問題,Ruby的標準庫中提供了一個名為Proc的類。Proc就是由塊轉換過來的物件。下面我們來看看把程式碼塊轉換為Proc的三種種方式:
1. 可以使用Proc.new方法來建立一個Proc, 這個Proc#call的方法,是一種被稱為延遲執行的技巧。
inc = Proc.new {|x| x+1}
inc.call(2) # => 3
- Ruby還有兩個核心方法將塊轉換為Proc:,首先介紹的是lambda方法:
dec = lambda {|x| x-1 }
dec.class # => Proc
dec.call(2) # => 1
- 我們還可以使用一種叫帶刺的(stabby)*lambda操作符建立lambda:
p = ->(x) { x + 1 }
其實它等價於:
p = lambda {|x| x+1 }
&操作符
在絕大多數情況下,在方法中可以通過yield語句直接執行一個程式碼塊,但是在下面兩種情況下,yeild就顯得力不從心了:
1. 想把程式碼塊傳遞給另外一個方法(甚至程式碼塊)
2. 想把程式碼塊轉換成Proc
在這種情況下,我們需要給程式碼塊去一個名字,要將程式碼塊附加到一個繫結上。我們可以給這個方法新增一個特殊的引數,這個引數必須是列表中的最後一個,而且是以&符號開頭。下面我們先來舉一個&符號的例子:
def math(a, b)
yield(a, b)
end
def do_math(a, b &operation)
math(a, b, &operation)
end
do_math(2, 3) {|x, y| x*y} #=>6
但是這裡有一個漏洞,那就是如果呼叫do_math方法時沒有附加程式碼塊,那麼&operation引數將被賦值成nil,這樣math方法中的yield操作將會失敗。
下面我們再看一種將程式碼塊轉化為Proc的方式。我們再來重新回顧一下&操作符的含義:這是以一個Proc物件,但是我想把它當作程式碼塊來使用。Proc是一種用於儲存程式碼塊用於以後執行的物件。所以在程式碼中,只要我們將&去掉,就能再次得到一個Proc物件:
def my_method(&the_proc)
the_proc
end
p = my_method {|name| "Hello, #{name}!"}
p.class # => Proc
p.call("Bill") # => "Hello, Bill"
當我們重新想把Proc物件轉換為程式碼塊,只要我們重新加上&操作符就好:
block/proc_to_block.rb
def my_method(greeting)
"#{greeting}, #{yield}"
end
my_proc = proc("Bill")
my_method("Hello", &my_proc)
相關文章
- ruby on rails 小技巧AI
- Ruby on Rails Ping ++ 支付AI
- Ruby on Rails 生成指定版本的 Rails 專案AI
- ruby on rails筆記和理解AI筆記
- Ruby on Rails Mountable vs. Full EngineAI
- Ruby on rails專案中 引入BootstrapAIboot
- 從NodeJS切換到Ruby on Rails - nikodunkNodeJSAI
- Rails並不是用Ruby編寫的AI
- 【Ruby on Rails全棧課程】2.7 塊(Block)和迭代器AI全棧BloC
- Ruby on Rails 動態渲染遠端程式碼執行漏洞 (CVE-2016-0752)AI
- Ruby on Rails中的MVC架構是如何工作的AIMVC架構
- 強大的Rails/Ruby開發工具:JetBrains RubyMine 2023 for macAIMac
- 肖威洞察 | Ruby on Rails 的快速學習的體系框架;AI框架
- 開發新手最容易犯的50個 Ruby on Rails 錯誤(1)AI
- 幽默:Ruby on Rails團隊提出Rail治理名單引發爭議AI
- 幽默:Ruby on Rails建立者DHH質疑無伺服器和微服務AI伺服器微服務
- Ruby 中的閉包-程式碼塊
- 從底層去認識 ruby 的load,require,gems,bundler,以及rails中的autoloadingUIAI
- 從0使用Ruby on Rails打造企業級RESTful API專案實戰之我的雲音樂AIRESTAPI
- [Ruby Summit 2018 話題分享] 模組化的 Rails,微服務以外的另一種選擇MITAI微服務
- 50行ruby程式碼開發一個區塊鏈區塊鏈
- 【棧】RailsAI
- [Ruby]format xml with RubyORMXML
- [譯] Ruby 2.6 String的split 方法支援程式碼塊執行
- 從Rails到Clojure再到Java,最後回到RailsAIJava
- Ruby 札記 - Ruby 集合家族之雜湊(Hash)
- Ruby 札記 - Ruby 集合家族之陣列(Array)陣列
- Rails Security (上)AI
- Rails安裝AI
- RubyMine 2022 Mac(Ruby程式碼編輯)Mac
- rails graphql的使用AI
- Rails 一對多AI
- Ruby 札記 - 淺嘗 Ruby 特性
- RubyMine 2022 for Mac(Ruby程式碼編輯器)Mac
- Ruby Profiler 詳解之 stackprof
- Ruby 札記 - 淺談和配置 Ruby
- Rails開發中使用byebug偵錯程式AI
- 如何在Rails應用程式中使用Kafka?AIKafka