Ruby菜鳥入門指南

寫這篇文章的初衷源於個人夥伴們在上手Ruby過程當中,表現實在是太讓人拙計了。因爲項目的急功近利,須要迅速入門Ruby並上手項目。因此不少開發者在實際開發過程當中,不熟悉Ruby的表達方式,也會沿用其餘語言比較生澀的表達形式。在我看來,Ruby的學習應該是個系統的按部就班的過程,儘可能避免急迫的方式。不過現實每每是緊迫的,因此就有了這篇文章。編程

標題中的菜鳥主要是指那些有其餘編程語言開發經驗,但在Ruby面前是個學習時間不久的初學者。個人工做夥伴都是這樣的一些人。因此,我就在考慮Ruby和其餘語言的一些顯著的不一樣點,想要提點他們注意這些地方,能將程序儘可能寫得Rubic。在我與其餘語言進行比較的過程當中,有了一些靈感,因此我就寫了點。後來靈感多了些,我也就多寫了些。設計模式

着重指出一點,沒有菜鳥開發者,只有停滯不前的開發者。系統學習一門語言才能自如地運用該語言的表達。Ruby的官方文檔是永遠是學習Ruby語言的最好資料,它最全面且持續更新。此外,Ruby的官方也給出了從其它語言到 Ruby的比較文檔。數組

字符串

在Java中,字符串只有雙引號的形式;在Python和JavaScript中,字符串既有單引號形式也有雙引號形式,但它們實踐是一回事。在Ruby的世界中,字符串的表達方式要豐富得多。Ruby中的字符串,既有單引號的形式,也有雙引號的形式,但它們的含義倒是大相徑庭的。ruby

單引號的字符串,指的是原生字符串,其中不含有轉義規則。例如'\n'不是指換行符,而是指兩個字符的字符串,分別爲字符\\和字符n閉包

雙引號的字符串,是包含轉義規則的。例如"\n"就是指換行符。另外,雙引號的字符串還可使用#{...}的方式嵌入表達式。less

"My Name is #{name}, and my years old is #{age}."

TODO 多行字符串編程語言

符號

Ruby引入符號的概念,是源於Ruby的一個設計缺陷。在大部分語言設計中,字符串都設計爲不可變對象;然而在Ruby當中,字符串被設計爲可變的。爲此,引入了另外一個字符序列的類型,但它是不可變的。這就是符號(Symbol)。學習

Ruby中符號的寫法是在文本前面加上冒號(:)。對於Ruby中合法的變量名,直接加上冒號便可,例如:設計

:name
:age
:kind_of_animal

也能夠在字符串前面加上冒號,這時符號的內容能夠包含空格等變量名不容許的字符。示例:code

:"My Name is #{name}, and my years old is #{age}."

這裏字符串的單引號和雙引號的性質也被沿用了下來。

符號是不可變的;而且,其是惟一的。對於內容徹底相同的符號,其只會有一個實例存在於Ruby解釋器環境中。

TODO 相同內容符號的object_id一致

符號對於Hash的構造有特殊的做用。Ruby中,Hash的構造比較繁瑣,要用到=>符號:

{ 'a' => 'a', 'b' => 'b', 'c' => 'c' }

可是若是鍵值都是符號的話,有簡便的構造方法:

{ a: 'a', b: 'b', c: 'c' }

它等價於:

{ :a => 'a', :b => 'b', :c => 'c' }

因爲在方法調用中最後一個Hash參數能夠省略大括號,因此下面的調用

f({ a: 'a', b: 'b', c: 'c' })

能夠去掉大括號,寫成:

f(a: 'a', b: 'b', c: 'c')

這就很像Python的關鍵字參數了。

最後,符號和字符串的相互轉化方式以下:

str.to_sym  #字符串轉化爲符號
sym.to_s    #符號轉化爲字符串

方法名是符號。

一切皆是對象

Java中有些基本數據類型(boolean、int、double),它們不是對象。JavaScript中的基本數據類型能夠理解爲對象,如boolean、number、string、function;但它們不能像普通的JS對象那樣自如地增刪屬性。Python要完全些,一切皆是對象,包括數字和布爾值都是普通的對象。

不過,比起全部其餘的語言,Ruby是貫徹一切皆是對象這一思想最完全的語言。在Ruby中:

  • 數字、布爾值、字符串、數組是對象。

  • 類是對象,它是Class類的實例。

  • 指示對象不存在的nil值也是對象,它是NilClass的實例,能夠調用方法to_s, to_i等。

一切皆是表達式

這多是Ruby又一個玄妙的地方了,影射了Ruby大一統的設計理念。Ruby中一切皆是表達式,一切表達方式都返回值。

  • 普通的Ruby表達式固然返回值。

  • if、while等控制結構返回值,其值是內部最後一條語句的值。

  • 方法調用返回值,其值由return指定或者是方法內最後一條語句的值。

  • 類定義返回值,其值是類內部最後一條語句的值。

  • 方法定義返回值,其值是方法名錶示的符號。

TODO 一切皆是表達式示例

一切皆是方法調用

Ruby是也是貫徹面向對象設計模式最完全的語言。在面向對象的設計理念中,爲了提高封裝性,會禁止直接的對象屬性操做,只給出相應的get和set方法。

而在Ruby中,從語言層級中就禁止了直接訪問對象屬性的途徑,只存在方法調用。咱們日常常見的a.namea.name = 'Hello'的調用方式,看上去很像是直接操做屬性,其實不是的。由於Ruby的方法調用能夠省略括號,因此

a.name

等價於

a.name()

a.name = 'Hello'

的形式,其實是

a.name=('Hello')

的簡寫。

TODO attr_reader, attr_writer, attr_accessor宏

省略分號

TODO 省略分號

省略括號的方法調用

Ruby中的方法調用,能夠省略括號:

f a, b, c

等價於:

f(a, b, c)

控制結構

TODO 控制結構:if-else,unless-else,when-case,while,begin-rescue-ensure

變量命名約定

面嚮對象語言中,根據做用域的不一樣,分別有全局變量、常量、類變量、實例變量、局部變量的區別。在其餘的語言中,多是經過不一樣的修飾符和做用域進行區別。例如在Java中,沒有全局變量的概念,常量用final修飾,類變量用static修飾,實例變量存在於類定義中,局部變量存在於方法定義中。有時候,這些變量很容易混淆;局部變量也很容易覆蓋掉實例變量和類變量。

在Ruby中,是以變量名的格式區別變量的類型。總結以下:

  • 局部變量:以小寫字母開頭

  • 常量:以大寫字母開頭

  • 實例變量:以@開頭

  • 類變量:以@@開頭

  • 全局變量:以$開頭

TODO 變量名示例

方法名約定

Ruby中的方法名結尾能夠跟?和!。通常來講,以?結尾的方法返回布爾值;以!結尾的方法提示危險性。例如字符串中,empty?返回字符串是否爲空;subsub!方法替換字符串,區別是sub不修改原字符串,返回替換的字符串;sub!做原地替換,會修改原字符串。

通常來說,返回布爾值的方法名以?結尾,會對原對象做潛在性的修改的方法名以!結尾。

Ruby中的方法不是一等公民。方法不是值,不能做爲參數傳遞給另外一個方法。不過Ruby有塊的概念,塊能夠做爲語言特性附加給方法調用。

塊的寫法有兩種形式,分別是大括號形式和do...end形式。

大括號形式:

{ |a, b|
    a.to_i <= b.to_i
}

do...end形式:

do |a, b|
    a.to_i <= b.to_i
end

乍一看,大括號的形式有點醜。通常來講,只在單行塊的時候用大括號的形式:

{ |a, b| a.to_i <= b.to_i }

Ruby中的每一個方法均可以接受一個塊。塊要緊接着方法調用的後面,不是方法的參數之一。例如

f(1, 2, 3) do |a, b|
    a.to_i <= b.to_i
end

上面的示例中省略括號也是合法的:

f 1, 2, 3  do |a, b|
    a.to_i <= b.to_i
end

但像下面這樣把塊用括號括起來做爲最後一個參數就是錯誤的:

f(1, 2, 3, { |a, b| a.to_i <= b.to_i }) #語法錯誤

塊與方法一個很大的區別是塊支持閉包:

min = 18

array.select do |v| 
    v >= min #訪問外層min變量 
end

TODO 在方法定義中用yield關鍵字調用塊

迭代器

Ruby中沒有提供Java和JavaScript當中三段for循環的模式。所謂三段for循環,是指下面JavaScript的for循環:

for(i = 0; i <= 9; i++) {
    console.log(i);
}

Ruby中沒有提供這樣的方式。但這並無什麼痛苦的,由於Ruby提供了基於塊的迭代方式。例如上面的代碼,在Ruby中能夠寫成:

0.upto(9) do |i|
    puts i
end

Ruby中的集合,都支持這樣傳遞代碼塊的迭代方式。Ruby中的集合包括Range、Array、Hash、String、etc。例如上面的示例能夠改寫成Range的each迭代形式:

(0..9).each do |i| 
    puts i
end

TODO -ect方法:collect, inject, select

真假值

Ruby中用於if、unless、while的條件判斷中,真假值的規則很簡潔:

  • nil和false爲假

  • 其他都爲真

TODO list

我懶!

相關文章
相關標籤/搜索