2015-11-27 96 views
0

我需要解密一些Ruby代碼。作爲一名Python開發人員,我很難理解一些語法。瞭解Ruby和Sinatra語法

我需要處理一些(主要是乾淨可讀的)Sinatra代碼。我開始用Sinatra tutorial,它看起來是這樣的:

get '/' do 
    "Hello, World!" 
end 

現在,我知道,在Ruby中,你不需要括號調用函數。因此,如果我想了解上述內容,我會說:

  1. get是一個函數,它將第一個參數作爲路由。
  2. '/'是第一個參數
  3. do ... end塊是一個匿名函數

請糾正我,如果我錯了上面,並詳細什麼我可能會丟失解釋。

他們還說Sinatra是一個DSL--這是否意味着它解析了一些不是官方Ruby的特殊語法?

+1

你上點1-3正確(儘管Ruby的塊是不是一個匿名函數*本身*,並非全部不同)。 Sinatra是一個DSL,但不是它不使用任何非Ruby語法。 –

回答

3

do ... end(或{ ... })是,這是Ruby中一個非常重要的概念。有人注意到,經常以其他功能爲參數的功能(map,filter,grep,timeout ...)經常接受單一功能。所以Ruby設計師決定爲它製作一個特殊的語法。

人們經常說,在Ruby中,一切都是一個對象。這不是真的:代碼不是一個對象。代碼可以將包裝成爲一個對象。但Ruby塊是純代碼 - 不是一個對象,也不是一個一階值。塊是與函數調用關聯的一段代碼。

您的代碼段相當於這樣的:

self.get('/') do 
    return "Hello, World!" 
end 

get方法採用一個參數和一個塊; 不是兩個參數。在一個假設的例子,其中get確實需要兩個參數,我們會寫這樣的事:

get('/', lambda { "Hello, World" }) 

get('/', Proc.new { "Hello, World" }) 

但是請注意,我們總結代碼到對象的方式需要調用方法lambdaProc.new - 並給他們一個塊(和零參數)!

有很多關於「Ruby塊」的教程,所以我不會鏈接任何特定的教程。

由於塊語法的緣故,Ruby非常擅長用非常整齊地表達某些概念的方言(仍然是完整的句法Ruby)。Sinatra使用get...「語法」(但實際上只是一個方法調用)來描述Web服務器; Rake使用task...「語法」來描述構建過程;測試框架RSpec擁有自己的描述所需行爲的DSL(仍然是Ruby)。

1

經過一番閱讀,我瞭解了代碼塊。

Ruby代碼塊很簡單。他們是'關閉'。有寫塊

do |x| 
    do_something(x) 
end 

{|x| do_something(x) } 

|x|兩種方式獲取傳遞到塊內的代碼參數。

掌握代碼塊的關鍵在於瞭解它們如何與方法一起使用。

在Ruby中,方法有點不同。

  • 除參數外,任何方法都可以接受代碼塊。
  • 代碼塊不參數,但它們可被傳遞給方法連同參數
  • 的方法可以選擇不調用代碼塊,在這種情況下,任何代碼塊,這是一個單獨的實體傳遞被忽略
  • 如果一個方法調用一個代碼塊,那麼在調用該方法時需要傳遞它,否則Ruby會發出抱怨。
  • yield的方法中執行的代碼塊

更多關於代碼塊閱讀:http://mixandgo.com/blog/mastering-ruby-blocks-in-less-than-5-minutes

+0

很好的答案,很高興你有一些見解。儘管Ruby塊不是關閉的,但它們*可以*。請參閱[本聊天](http://www.artima.com/intv/closures.html)與Matz(Ruby的創建者)和[本文有用的文章](http://www.reactive.io/tips/2008/12/21/understanding-ruby-blocks-procs-and-lambdas /)來獲取塊,proc和lambdas背後的細微差別。 – iain