亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Ruby > 正文

總結Ruby的語法和語言的特性

2020-02-24 15:36:54
字體:
來源:轉載
供稿:網友

Ruby是一種解釋性的、面向對象的動態語言,Ruby的策略是在靈活性和運行安全之間找到平衡,隨著Rails框架的出現,Ruby也獲得了驚人的成功,下面就讓武林技術頻道小編為你總結Ruby的語法和語言的特性。

1. 基礎
在Ruby交互命令行中輸入以下命令(>>為命令行提示符,=>為返回值;下文將把=>符號和語句寫在一行內表明其返回值):

ruby;">>> puts 'hello, world'hello, world=> nil>> language = 'Ruby'=> "Ruby">> puts "hello, #{language}"hello, Ruby=> nil

以上代碼使用puts輸出,給變量賦值,并用#{}的語法實現字符串替換。這表明Ruby是解釋執行的;變量無需聲明即可直接初始化和賦值;每條Ruby代碼都會返回某個值;單引號包含的字符串表示它將直接被解釋,雙引號包含的字符串會引發字符串替換。

1.1 編程模型

Ruby是一門純面向對象語言,在Ruby中一切皆為對象,可以用“.”調用對象具有的方法,可以通過class和methods方法查看對象的類型及支持的方法,如4.class => Fixnum,7.methods => ["inspect", "%", "<<", "numerator", ...],false.class => FalseClass(方括號表示數組)。

1.2 流程控制

條件判斷有正常的塊形式,也有簡單明了的單行形式;除了常見的if語句外,還有unless語句(等價于if not,但可讀性更強)。同理,循環也有正常的塊形式和單行形式。注意:除了nil和false之外,其他值都代表true,包括0!

# 塊形式if x == 4 puts 'This is 4.'end# 單行形式puts 'This is false.' unless truex = x + 1 while x < 10 # x的結果為10x = x - 1 until x == 1 # x的結果為1

和其他C家族的語言差不多,Ruby的邏輯運算符and(&&)、or(||)都自帶短路功能,若想執行整個表達式,可以用&或|

1.3 鴨子類型

執行4 + 'four'會出現TypeError的錯誤,說明Ruby是強類型語言,在發生類型沖突時,將得到一個錯誤。如果把個語句放在def...end函數定義中,則只有在調用函數時才會報錯,說明Ruby在運行時而非編譯時進行類型檢查,這稱為動態類型。Ruby的類型系統有自己的潛在優勢,即多個類不必繼承自相同的父類就能以“多態”的方式使用:

a = ['100', 100.0]puts a[0].to_i # => 100puts a[1].to_i # => 100

這就是所謂的“鴨子類型”(duck typing)。數組的第一個元素是String類型,第二個元素是Float類型,但轉換成整數用的都是to_i。鴨子類型并不在乎其內在類型是什么,只要一個對象像鴨子一樣走路,像鴨子一樣嘎嘎叫,那它就是只鴨子。在面向對象設計思想中,有一個重要原則:對接口編碼,不對實現編碼。如果利用鴨子類型,實現這一原則只需極少的額外工作,就能輕松完成。

1.4 函數

def tell_the_truth trueend

每個函數都會返回結果,如果沒有顯式指定返回值,函數就將退出函數前最后處理的表達式的值返回。函數也是個對象,可以作為參數傳給其他函數。

1.5 數組

和Python一樣,Ruby的數組也是用中括號來定義,如animals = ['lion', 'tiger', 'bear'];負數下標可以返回倒數的元素,如animals[-1] => "bear";通過指定一個Range對象來獲取一個區段的元素,如animals[1..2] => ['tiger', 'bear']。此外,數組元素可以互不相同,多為數組也不過是數組的數組。數組擁有極其豐富的API,可用其實現隊列、鏈表、棧、集合等等。

1.6 散列表

numbers = {2 => 'two', 5 => 'five'}stuff = {:array => [1, 2, 3], :string => 'Hi, mom!'}# stuff[:string] => "Hi, mom!"

散列表可以帶任何類型的鍵,上述代碼的stuff的鍵較為特殊——它是一個符號(symbol),前面帶有冒號標識符。符號在給事物和概念命名時很好用,例如兩個同值字符串在物理上不同,但相同的符號卻是同一物理對象,可以通過反復調用'i am string'.object_id和:symbol.object_id來觀察。另外,當散列表用作函數最后一個參數時,大括號可有可無,如tell_the_truth :profession => :lawyer。

2. 面向對象
2.1 代碼塊

代碼塊是沒有名字的函數(匿名函數),可以用作參數傳遞給函數。代碼塊只占一行時用大括號包起來,占多行是用do/end包起來,可以帶若干個參數。

3.times {puts 'hehe'} # 輸出3行hehe['lion', 'tiger', 'bear'].each {|animal| puts animal} # 輸出列表的內容

上面的times實際上是Fixnum類型的方法,要自己實現這樣一個方法非常容易:

class Fixnum def my_times  i = self   while i > 0    i = i - 1    yield  end endend
3.my_times {puts 'hehe'} # 輸出3行hehe

這段代碼打開一個現有的類,向其中添加一個自定義的my_times方法,并用yield調用代碼塊。在Ruby中,代碼塊不僅可用于循環,還可用于延遲執行,即代碼塊中的行為只有等到調用相關的yield時才會執行。代碼塊充斥于Ruby的各種庫,小到文件的每一行,大到在集合上進行各種復雜操作,都是由代碼塊來完成的。

2.2 類

調用一個對象的class方法可以查看其類型,調用superclass可以查看這個類型的父類。下圖展示了數字的繼承鏈,其中橫向箭頭表示右邊是左邊實例化的對象,縱向箭頭表示下邊繼承于上邊。Ruby的一切事物都有一個共同的祖先Object。

2016612151714257.png (685×376)

最后通過一個完整的實例——定義一棵樹,來看下Ruby的類如何定義和使用,該注意的點都寫在注釋里面了。

class Tree # 定義實例變量,使用attr或attr_accessor關鍵字,前者定義變量和訪問變量的同名getter方法(即只讀),后者定義的變量多了同名setter方法(注意這里使用了符號) attr_accessor :children, :node_name # 構造方法(構造方法必須命名為initialize) def initialize(name, children=[])  @node_name = name  @children = children end # 遍歷所有節點并執行代碼塊block,注意參數前加一個&表示將代碼塊作為閉包傳遞給函數 def visit_all(&block)  visit &block  children.each {|c| c.visit_all &block} end # 訪問一個節點并執行代碼塊block def visit(&block)  block.call self endendruby_tree = Tree.new("Ruby",  [Tree.new("Reia"),  Tree.new("MacRuby")])# 訪問一個節點ruby_tree.visit {|node| puts node.node_name}# 訪問整棵樹ruby_tree.visit_all {|node| puts "Node: #{node.node_name}"}

再提一下Ruby的命名規范:

(1)類采用CamelCase命名法
(2)實例變量(一個對象有一個值)前必須加上@,類變量(一個類有一個值)前必須加上@@
(3)變量和方法名全小寫用下劃線命名法,如underscore_style
(4)常量采用全大寫下劃線命名法,如ALL_CAPS_STYLE
(5)用于邏輯測試的函數和方法一般要加上問號,如if test?

3. 模塊與混入(Mixin)
面向對象語言利用繼承,將行為傳播到相似的對象上。若一個對象像繼承多種行為,一種做法是用多繼承,如C++;Java采用接口解決這一問題,Ruby采用模塊Mixin。模塊是函數和常量的集合,若在類中包含一個模塊,那么該模塊的行為和常量也會成為類的一部分。

# 定義模塊ToFilemodule ToFile # 獲取文件名 def filename  "object_name.txt" end # 創建文件 def to_f  File.open(filename, 'w') {|f| f.write(to_s)} # 注意這里to_s在其他地方定義! endend# 定義用戶類class Person include ToFile attr_accessor :name def initialize(name)  @name = name end def to_s  name endendPerson.new('matz').to_f # 創建了一個文件object_name.txt,里面包含內容matz

上面的代碼很好理解,只是有一點要注意:to_s在模塊中使用,在類中實現,但定義模塊的時候,實現它的類甚至還沒有定義。這正是鴨子類型的精髓所在。寫入文件的能力,和Person這個類沒有一點關系(一個類就應該做屬于它自己的事情),但實際開發又需要把Person類寫入文件這種額外功能,這時候mixin就可以輕松勝任這種要求。

Ruby有兩個重要的mixin:枚舉(enumerable)和比較(comparable)。若想讓類可枚舉,必須實現each方法;若想讓類可比較,必須實現<=>(太空船)操作符(比較a,b兩操作數,返回1、0或-1)。Ruby的字符串可以這樣比較:'begin' <=> 'end => -1。數組有很多好用的方法:

a = [5, 3, 4, 1]a.sort => [1, 3, 4, 5] # 整數已通過Fixnum類實現太空船操作符,因此可比較可排序a.any? {|i| i > 4} => truea.all? {|i| i > 0} => truea.collect {|i| i * 2} => [10, 6, 8, 2]a.select {|i| i % 2 == 0} => [4]a.member?(2) => falsea.inject {|product, i| product * i} => 60 # 第一個參數是代碼塊上一次執行的結果,若不設初始值,則使用列表第一個值作為初始值

4. 元編程(metaprogramming)
所謂元編程,說白了就是“寫能寫程序的程序”,這說起來有點拗口,下面會通過實例來講解。

4.1 開放類

可以重定義Ruby中的任何類,并給它們擴充任何你想要的方法,甚至能讓Ruby完全癱瘓,比如重定義Class.new方法。對于開發類來說,這種權衡主要考慮了自由,有這種重定義任何類或對象的自由,就能寫出即為通俗易懂的代碼,但也要明白,自由越大、能力越強,擔負的責任也越重。

class Numeric def inches  self end def feet  self * 12.inches end def miles  self * 5280.feet end def back  self * -1 end def forward  self endend

上面的代碼通過開放Numeric類,就可以像這樣采用最簡單的語法實現用英寸表示距離:puts 10.miles.back,puts 2.feet.forward。

4.2 使用method_missing

Ruby找不到某個方法時,會調用一個特殊的回調方法method_missing顯示診斷信息。通過覆蓋這個特殊方法,可以實現一些非常有趣且強大的功能。下面這個示例展示了如何用簡潔的語法來實現羅馬數字。

class Roman # 覆蓋self.method_missing方法 def self.method_missing name, *args  roman = name.to_s  roman.gsub!("IV", "IIII")  roman.gsub!("IX", "VIIII")  roman.gsub!("XL", "XXXX")  roman.gsub!("XC", "LXXXX")  (roman.count("I") +   roman.count("V") * 5 +   roman.count("X") * 10 +   roman.count("L") * 50 +   roman.count("C") * 100) endendputs Roman.III # => 3puts Roman.XII # => 12

我們沒有給Roman類定義什么實際的方法,但已經可以Roman類來表示任何羅馬數字!其原理就是在沒有找到定義方法時,把方法名稱和參數傳給method_missing執行。首先調用to_s把方法名轉為字符串,然后將羅馬數字“左減”特殊形式轉換為“右加”形式(更容易計數),最后統計各個符號的個數和加權。

當然,如此強有力的工具也有其代價:類調試起來會更加困難,因為Ruby再也不會告訴你找不到某個方法。因此method_missing是一把雙刃劍,它確實可以讓語法大大簡化,但是要以人為地加強程序的健壯性為前提。

4.3 使用模塊

Ruby最流行的元編程方式,非模塊莫屬。下面的代碼講述如何用模塊的方式擴展一個可以讀取csv文件的類。

module ActsAsCsv # 只要某個模塊被另一模塊include,就會調用被include模塊的included方法 def self.included(base)  base.extend ClassMethods end module ClassMethods  def acts_as_csv   include InstanceMethods  end end module InstanceMethods  attr_accessor :headers, :csv_contents  def initialize   read  end  def read   @csv_contents = []   filename = self.class.to_s.downcase + '.txt'   file = File.new(filename)   @headers = file.gets.chomp.split(', ') # String的chomp方法去除字符串末尾的回車換行符   file.each do |row|    @csv_contents << row.chomp.split(', ')   end  end endend # end of module ActsAsCsvclass RubyCsv  # 沒有繼承,可以自由添加 include ActsAsCsv acts_as_csvendm = RubyCsv.newputs m.headers.inspectputs m.csv_contents.inspect

上述代碼中RubyCsv包含了ActsAsCsv,所以ActsAsCsv的included方法中,base就指RubyCsv,ActsAsCsv模塊給RubyCsv類添加了唯一一個類方法acts_as_csv,這個方法又打開RubyCsv類,并在類中包含了所有實例方法。如此這般,就寫了一個會寫程序的程序(通過模塊來動態添加類方法)。

一些出色的Ruby框架,如Builder和ActiveRecord,都會為了改善可讀性而特別依賴元編程。借助元編程的威力,可以做到盡量縮短正確的Ruby語法與日常用于之間的距離。注意一切都是為了提升代碼可讀性而服務。

5. 總結
Ruby的純面向對象可以讓你用一致的方式來處理對象。鴨子類型根據對象可提供的方法,而不是對象的繼承層次,實現了更切合實際的多態設計。Ruby的模塊和開放類,使程序員能把行為緊密結合到語法上,大大超越了類中定義的傳統方法和實例變量。
核心優勢:
(1)優雅的語法和強大的靈活性
(2)腳本:Ruby是一門夢幻般的腳本語言,可以出色地完成許多任務。Ruby許多語法糖可以大幅提高生產效率,各種各樣的庫和gem(Ruby包)可以滿足絕大多數日常需要。
(3)Web開發:很多人學Ruby最終就是為了用Ruby on Rails框架來進行Web開發。作為一個極其成功的MVC框架,其有著廣泛的社區支持及優雅的語法。Twitter最初就是用Ruby實現的,借助Ruby無比強大的生產力,可以快速地開發出一個可推向市場的合格產品。
不足之處:
(1)性能:這是Ruby的最大弱點。隨著時代的發展,Ruby的速度確實是越來越快。當然,Ruby是創建目的為了改善程序員的體驗,在對性能要求不高的應用場景下,性能換來生產效率的大幅提升無疑是值得的。
(2)并發和面向對象編程:面向對象是建立在狀態包裝一系列行為的基礎上,但通常狀態是會改變的。程序中存在并發時,這種編程策略就會引發嚴重問題。
(3)類型安全:靜態類型可提供一整套工具,可以更輕松地構造語法樹,也因此能實現各種IDE。對Ruby這種動態類型語言來說,實現IDE就困難得多。

以上就是武林技術頻道小編介紹的關于總結Ruby的語法和語言的特性,我們可以看到程序是越來越人性化了,想要了解更多的小伙伴,歡迎關注武林技術頻道了解更多哦。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品99久久久久久www| 亚洲无限乱码一二三四麻| 亚洲电影在线观看| 在线视频免费一区二区| 国产91精品久久久久久久| 精品国产区一区二区三区在线观看| 亚洲一区亚洲二区亚洲三区| 国产精品91久久久| 影音先锋欧美精品| 538国产精品视频一区二区| 中文字幕国产精品| 在线观看中文字幕亚洲| 色噜噜久久综合伊人一本| 久久久久久国产精品| 日本一区二区不卡| 5566成人精品视频免费| 91日韩在线播放| 亚洲国产精品一区二区久| 久久精品电影网| 欧美在线视频观看免费网站| www.日韩不卡电影av| 日本在线观看天堂男亚洲| 亚洲最大成人免费视频| 亚洲欧美综合图区| 欧美成年人在线观看| 欧美日韩性生活视频| 亚洲天堂第一页| 最好看的2019的中文字幕视频| 国产一区二区成人| 日韩黄在线观看| 色伦专区97中文字幕| 热久久这里只有精品| 精品久久香蕉国产线看观看亚洲| 国产一区二区三区网站| 亚洲欧美另类自拍| 日韩在线免费视频观看| 在线播放国产一区二区三区| 欧美在线一级va免费观看| 国产不卡av在线免费观看| 国产精品男人爽免费视频1| 综合国产在线视频| 成人免费激情视频| 亚洲字幕在线观看| 精品露脸国产偷人在视频| 美女性感视频久久久| 久久精品91久久久久久再现| 尤物精品国产第一福利三区| 中文字幕亚洲国产| 日韩视频精品在线| 国产日本欧美一区二区三区在线| 精品综合久久久久久97| 日韩av在线资源| 亚洲免费精彩视频| 亚洲免费小视频| 91理论片午午论夜理片久久| 亚洲精品小视频| 日韩电影大全免费观看2023年上| 国产综合色香蕉精品| 疯狂做受xxxx高潮欧美日本| 欧美激情按摩在线| 欧美多人乱p欧美4p久久| 少妇精69xxtheporn| 久久91精品国产| 精品国产欧美一区二区五十路| 98精品国产高清在线xxxx天堂| 久久精品国产v日韩v亚洲| 2019中文在线观看| 国产精品一香蕉国产线看观看| 国产精品第8页| 亚洲欧美激情四射在线日| 久热精品在线视频| 国产精品吴梦梦| 91黑丝高跟在线| 欧美午夜www高清视频| 中文亚洲视频在线| 成人午夜激情网| 伊人久久大香线蕉av一区二区| 欧美日韩亚洲成人| 欧美一级大片视频| 中文字幕欧美精品日韩中文字幕| 久久久国产一区二区三区| 精品高清美女精品国产区| 国产精品高潮视频| 成人精品在线视频| 欧美电影免费观看大全| 精品亚洲一区二区三区在线观看| 91精品国产免费久久久久久| 欧美交受高潮1| 日韩hd视频在线观看| 在线播放国产一区二区三区| 国产精品国产亚洲伊人久久| 日韩在线观看免费全集电视剧网站| 日本欧美国产在线| 久久久久久久电影一区| 亚洲精品国产美女| 日韩亚洲欧美成人| 91麻豆国产精品| 狠狠躁夜夜躁人人躁婷婷91| 伊人久久综合97精品| 欧美乱妇高清无乱码| 国产精品成人国产乱一区| 国产亚洲xxx| 91精品国产91久久久久久最新| 国产精品免费视频xxxx| 欧美中文字幕在线观看| 欧美大片第1页| 91色琪琪电影亚洲精品久久| 欧美裸体xxxxx| 国产欧美精品久久久| 色综合91久久精品中文字幕| 91久久精品国产| 欧美国产第一页| 欧美亚洲国产日韩2020| 波霸ol色综合久久| 亚洲美女www午夜| 国内精品免费午夜毛片| 国产一区二区三区在线观看视频| 久久精品成人欧美大片古装| 国产亚洲精品久久久久动| 91久久久国产精品| 日韩精品在线免费观看视频| 久久久精品2019中文字幕神马| 亚洲成人黄色在线| 欧美电影免费观看网站| 亚洲美女自拍视频| 亚洲香蕉在线观看| 国产精品成久久久久三级| 成人97在线观看视频| 欧美激情奇米色| 国产一区二区三区网站| 欧美激情在线观看视频| 亚洲深夜福利视频| 精品国产一区二区在线| 久久天天躁夜夜躁狠狠躁2022| 欧美成人性生活| 精品国产乱码久久久久酒店| 国产精品十八以下禁看| 美女扒开尿口让男人操亚洲视频网站| 久久久久久久一区二区三区| 日本高清视频一区| 欧美日韩国产激情| 欧美丰满少妇xxxxx| 亚洲加勒比久久88色综合| 亚洲欧美日韩图片| 欧美激情xxxx| 大胆人体色综合| 91精品久久久久久久久久入口| 91香蕉国产在线观看| 日韩中文字幕在线视频| 国产精品久久久久av免费| 久久大大胆人体| 欧美激情视频网站| 亚洲电影免费观看高清完整版在线| 91香蕉亚洲精品| 成人av番号网| 68精品国产免费久久久久久婷婷| 欧美精品18videosex性欧美| 欧美日韩一区二区三区在线免费观看| 国产欧美在线视频| 51ⅴ精品国产91久久久久久| 国产一区二区动漫| 伊人久久男人天堂| 亚洲国产精品va| 亚洲精品国产欧美|