日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
牛人點(diǎn)評(píng)Ruby語(yǔ)言十大令人喜愛(ài)的特點(diǎn)

【精選譯文】我每天都要用 Ruby 工作,久而久之,我現(xiàn)在真的喜歡上使用它了。(編者注:本文作者Yehuda Katz是Ruby on Rails核心開(kāi)發(fā)團(tuán)隊(duì)的成員,以及Merb項(xiàng)目的主要推動(dòng)者。)下面是一個(gè)列表,列出了我最喜歡的 Ruby 語(yǔ)言特點(diǎn)。一些特點(diǎn)顯而易見(jiàn),一些特點(diǎn)也存在于其他語(yǔ)言中。分享 Ruby 這些我喜歡的特點(diǎn),并非是為了和其他語(yǔ)言進(jìn)行比較和對(duì)比。

目前創(chuàng)新互聯(lián)已為數(shù)千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)頁(yè)空間、綿陽(yáng)服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計(jì)、瑪曲網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶(hù)導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶(hù)和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。

編輯推薦:Ruby入門(mén)教程與技巧大全

1. 動(dòng)態(tài)類(lèi)型

靜態(tài)類(lèi)型語(yǔ)言也有很不錯(cuò)的功能,比如編譯時(shí)驗(yàn)證和 IDE 支持。不過(guò)根據(jù)我的經(jīng)驗(yàn),動(dòng)態(tài)類(lèi)型對(duì)于項(xiàng)目啟動(dòng)真的有很大幫助,并且便于進(jìn)行更改,尤其是在項(xiàng)目的早期到中期這些階段。

為了能夠讓我能夠輕松地繼續(xù)對(duì)象交換,我不需要為新對(duì)象創(chuàng)建正式的接口,這點(diǎn)讓人很開(kāi)心。

2. Duck Typing(鴨子類(lèi)型)

這只是動(dòng)態(tài)類(lèi)型的一個(gè)有效的擴(kuò)展。在 Ruby 中,預(yù)期能夠?qū)ψ址畬?duì)象進(jìn)行操作的方法并不會(huì)檢查 is_a?(String)。它們檢查對(duì)象是否 respond_to?(:to_str),如果是,就接著調(diào)用對(duì)象的 to_str。與此類(lèi)似,在 Ruby 中表示路徑(Path)的對(duì)象能夠?qū)崿F(xiàn)一個(gè) to_path 方法為提供路徑重現(xiàn)(representation)。

在 Rails 語(yǔ)言中,對(duì)于具有“模型”特性的對(duì)象,我們可以使用這樣的技巧來(lái)實(shí)現(xiàn)對(duì)它們 respond_to?(:to_model) 的預(yù)期。如果這些對(duì)象能夠?yàn)槲覀兲峁┮粋€(gè)它們自身的“模型”重現(xiàn),我們就能夠在相關(guān)語(yǔ)境中支持任何類(lèi)型。之前曾發(fā)布過(guò)有關(guān)Ruby中鴨子類(lèi)型的介紹,可以參考一二。

3. 令人嘆為觀止的模塊

Ruby 提供了一個(gè)與 Scala、Squeak 和 Perl 語(yǔ)言中“traits”類(lèi)似的功能。事實(shí)上,Ruby 模塊可以在運(yùn)行時(shí)動(dòng)態(tài)地址類(lèi)等級(jí)中添加新元素。運(yùn)行時(shí)可以動(dòng)態(tài)地對(duì) super 的使用繼續(xù)評(píng)估以考慮所有添加的模塊,這樣就可以方便地按照所需多次地?cái)U(kuò)展超類(lèi)功能,而且無(wú)需指定在類(lèi)聲明時(shí)確定super的加載地點(diǎn)。

此外,Ruby 模塊提供了生命周期鉤子(hook)append_features 和 included,這樣就可以使用模塊來(lái)互相隔離擴(kuò)展以及在特性包含的基礎(chǔ)上動(dòng)態(tài)的擴(kuò)展類(lèi)。

4. 類(lèi)主體不是專(zhuān)用的

在 Ruby 中,類(lèi)主體不是專(zhuān)用的語(yǔ)境。它們僅僅是一個(gè)對(duì)象類(lèi)的自身指向點(diǎn)。如果你用過(guò) Rails,你可能看到這樣的代碼:

 
 
 
  1. class Comment < ActiveRecord::Base  
  2.   validates_presence_of :post_id 
  3. end 

validates_presence_of 看起來(lái)好像是語(yǔ)言的一項(xiàng)功能,但實(shí)際上它是 Comment 上調(diào)用的方法,而 Comment 由 ActiveRecord::Base 提供。

該方法可以類(lèi)中的執(zhí)行任意代碼(arbitrary code),包括創(chuàng)建新的方法,執(zhí)行代碼中其他內(nèi)容,或者更新類(lèi)實(shí)例變量。與必須在編譯時(shí)運(yùn)行的 Java 標(biāo)注不同,Ruby 類(lèi)主體能夠考慮到運(yùn)行時(shí)的信息,如動(dòng)態(tài)提供的選項(xiàng)或其他代碼的評(píng)估結(jié)果。

5. 字符串求值(eval 功能)

這可能是一個(gè)不同的想法。這里我不是指任意運(yùn)行時(shí)字符串的求值,而是用于在 Ruby 程序啟動(dòng)過(guò)程中創(chuàng)建方法的字符串求值。

這樣就能夠利用 Ruby 定義的結(jié)構(gòu)(如 Rails 路徑或 AOP 定義),并且能夠?qū)⑵渚幾g到 Ruby 方法中。當(dāng)然,也可以將其作為其他語(yǔ)言的附件(add-on)來(lái)實(shí)現(xiàn),但在純 Ruby 環(huán)境中實(shí)現(xiàn)這類(lèi)功能是可能的。在很大程度上,它是一種自足執(zhí)行(self-hosting)的一種語(yǔ)言。

6. 區(qū)塊和 Lambda 表達(dá)式

我已經(jīng)說(shuō)過(guò)多次,這里再重復(fù)一次:我認(rèn)為沒(méi)有匿名 lambda 表達(dá)式的語(yǔ)言還沒(méi)有足夠強(qiáng)大到讓我每天使用它。這些構(gòu)造事實(shí)上非常常見(jiàn),在 Ruby、JavaScript、Scala、Clojure 和 Lisp 中也存在。之前介紹過(guò)Ruby 1.9中的Lambda表達(dá)式,有興趣的讀者可以看看。

利用它們,就能夠?qū)崿F(xiàn)看起來(lái)好像是語(yǔ)言功能的區(qū)塊范圍內(nèi)的構(gòu)造。最常見(jiàn)的使用示例是對(duì)文件的操作。在沒(méi)有 lambda 的語(yǔ)言中,用戶(hù)不得不在同一個(gè)語(yǔ)法范圍(和他們最初打開(kāi)的文件一致)中使用一段“確?!眳^(qū)塊,以確保關(guān)閉了資源。

在 Java 中:

 
 
 
  1. static void run(String in)   
  2. throws FileNotFoundException {  
  3.   File input = new File(in);  
  4.   String line; Scanner reader = null;  
  5.   try {  
  6.     reader = new Scanner(input);  
  7.     while(reader.hasNextLine()) {  
  8.       System.out.println(reader.nextLine());  
  9.     }  
  10.   } finally { reader.close(); }  

Java 版的代碼常常需要在 try 區(qū)塊中包括 Scanner 的創(chuàng)建以保證其關(guān)閉。相反,讓我們看看 Ruby 的代碼:

   
   
   
  1. def run(input)  
  2.   File.open(input, "r") do |f|  
  3.     f.each_line {|line| puts line }  
  4.   end 
  5. end 

由于區(qū)塊的存在,我們可以省去在單個(gè)位置關(guān)閉文件的麻煩,將程序員錯(cuò)誤減少到最小并且能夠減少重復(fù)。

#p#

7. 功能組合:自足執(zhí)行(self-hosting)語(yǔ)言

以上特點(diǎn)組合組合在一起,讓我們能夠在 Rails 中“擴(kuò)展”Ruby 語(yǔ)言??聪旅孢@段代碼:

     
     
     
  1. respond_to do |format|  
  2.   if @user.save  
  3.     flash[:notice] = 'User was successfully created.' 
  4.     format.html { redirect_to(@user) }  
  5.     format.xml { render :xml => @user, :status =>ted, :location => @user }  
  6.   else 
  7.     format.html { render :action => "new" }  
  8.     format.xml { render :xml => @user.errors, :status => :unprocessable_entity }  
  9.   end 
  10. end 

在這個(gè)示例中,我們可以無(wú)縫地將方法(respond_to)與正常的 Ruby 代碼(if 和 else))混合在一起,以生成一個(gè)新的區(qū)塊范圍的構(gòu)造。Ruby 的區(qū)塊語(yǔ)法讓我們能夠在區(qū)塊內(nèi)使用 return 和 yield,從而進(jìn)一步混合代碼區(qū)塊與語(yǔ)言構(gòu)造(如 if 或while 的界限)。

在 Rails 3 中,我們引入下面一段代碼:

       
       
       
  1. class PeopleController < ApplicationController  
  2.   respond_to :html, :xml, :json 
  3.    
  4.   def index  
  5.     @people = Person.find(:all)  
  6.     respond_with(@people)  
  7.   end 
  8. end 

這里,我們?cè)陬?lèi)中提供 respond_to。它告訴 Rails:respond_with(在 index 中)應(yīng)接收 HTML、XML、或 JSON 作為響應(yīng)格式。如果用戶(hù)請(qǐng)求不同的格式,我們將自動(dòng)返回一個(gè) 406 錯(cuò)誤(Not Acceptable)。

如果再稍微深入挖掘一下,你會(huì)看到 respond_to 方法被定義為:

         
         
         
  1. def respond_to(*mimes)  
  2.   options = mimes.extract_options!  
  3.    
  4.   only_actions   = Array(options.delete(:only))  
  5.   except_actions = Array(options.delete(:except))  
  6.    
  7.   mimes.each do |mime|  
  8.     mime = mime.to_sym  
  9.     mimes_for_respond_to[mime]          = {}  
  10.     mimes_for_respond_to[mime][:only]   = only_actions   unless only_actions.empty?  
  11.     mimes_for_respond_to[mime][:except] = except_actions unless except_actions.empty?  
  12.   end 
  13. end 

這個(gè)方法在 ActionController::MimeResponds::ClassMethods 模塊上定義,而該模塊屬于 ActionController::Base。此外,在該模塊的生命周期鉤子 included 中使用 class_inheritable_reader 定義了 mimes_for_respond_to。class_inheritable_reader method (macro?)。 使用 class_eval 將方法添加到正在使用的類(lèi)上,以模擬內(nèi)置的 attr_accessor 功能。

是否理解所有這些細(xì)節(jié)無(wú)關(guān)緊要。重要的是利用上述的 Ruby 功能,我們就可以創(chuàng)建抽象層,從而能夠?yàn)?Ruby 語(yǔ)言添加新的特性。

開(kāi)發(fā)者看到 ActionController::MimeResponds,他無(wú)需去了解 class_inheritable_reader 如何運(yùn)行——他只需了解這個(gè)基本功能。而看到 API 文檔的開(kāi)發(fā)者也無(wú)需了解 class-levelrespond_to 如何運(yùn)行——他只需了解這個(gè)已經(jīng)提供的功能。

這樣,剝離每一層就可以在其他抽象上構(gòu)造一個(gè)簡(jiǎn)單的抽象。沒(méi)有必要一次剝離所有抽象層。

8. 很好的字面含義

在使用 Ruby 編程時(shí),我常常會(huì)忘記這一點(diǎn);只有在使用一些字面意義很少或表達(dá)很差的語(yǔ)言時(shí),我才會(huì)體會(huì)到 Ruby 的這一優(yōu)點(diǎn)。

Ruby 中每個(gè)詞都具有很好的字面意義:

  1. 字符串:single-line、double-line、interpolated
  2. 數(shù)字: binary、octal、decimal、hex
  3. 空值:nil
  4. 布爾瑪:true、false
  5. 數(shù)組: [1,2], %w(每個(gè)字都是元素)
  6. 哈希表(Hash): {key => value} 和{key: value}(Ruby 1.9)
  7. 正則表達(dá)式:/hello/、%r{hello/path}、%r{hello#{interpolated}}
  8. 符號(hào)::name 和 :”weird string”
  9. 區(qū)塊:{ 區(qū)塊文字 }

我想我可能會(huì)漏掉一些。雖然有些學(xué)術(shù)性,但可讀性良好的語(yǔ)句的確能夠增強(qiáng)開(kāi)發(fā)者的編碼能力,讓他們寫(xiě)出簡(jiǎn)短而***表達(dá)性的代碼。

當(dāng)然,通過(guò)對(duì)新的 Hash 對(duì)象實(shí)例化并一個(gè)一個(gè)地輸入關(guān)鍵字和值,你也可以實(shí)現(xiàn) Hash 的功能。但這減少了 Hash 的用途,比如作為方法參數(shù)。

Hash 字面上的簡(jiǎn)潔性讓 Ruby 程序員能夠無(wú)需經(jīng)過(guò)語(yǔ)言設(shè)計(jì)者的許可就能夠添加限制性關(guān)鍵字參數(shù)。這也是自足執(zhí)行的又一個(gè)實(shí)例。

9. 所有事物都是對(duì)象,所有代碼都是可執(zhí)行的并具有 self

很大程度上,類(lèi)主體之所以能夠按照這樣的方式運(yùn)行,是 Ruby 語(yǔ)言始終如一地面向?qū)ο蟮慕Y(jié)果。在類(lèi)主體內(nèi)部,Ruby 僅執(zhí)行具有指向類(lèi)的 self 的代碼。此外,類(lèi)內(nèi)容中沒(méi)有什么是專(zhuān)用的;可以在任何位置對(duì)類(lèi)語(yǔ)境中的代碼進(jìn)行求值。

比如:

           
           
           
  1. module Util  
  2.   def self.evaluate(klass)  
  3.     klass.class_eval do 
  4.       def hello  
  5.         puts "#{self} says Hello!"   
  6.       end 
  7.     end 
  8.   end 
  9. end 
  10.    
  11. class PersonName < String 
  12.   Util.evaluate(self)  
  13. end 

這完全等同于:

             
             
             
  1. class PersonName < String 
  2.   def hello  
  3.     puts "#{self} says Hello!"   
  4.   end 
  5. end 

Ruby 移除了不同位置代碼之間的人工界限,降低了創(chuàng)建抽象的概念上的成本。這是強(qiáng)大的、始終如一的對(duì)象建模的結(jié)果。

有關(guān)該主體,再提供一個(gè)示例。Ruby 常見(jiàn)的術(shù)語(yǔ):possibly_nil && possibly_nil.method_name。由于 nil 只是 Ruby 的一個(gè)對(duì)象,向它發(fā)送一個(gè)它無(wú)法理解的信息,會(huì)造成一個(gè) NoMethodError 錯(cuò)誤。有些開(kāi)發(fā)者建議使用這種句法:possibly_nil.try(:method_name)??梢栽?Ruby 中通過(guò)以下代碼來(lái)實(shí)現(xiàn):

               
               
               
  1. class Object 
  2.   alias_method :try, :__send__  
  3. end 
  4.    
  5. class NilClass 
  6.   def try  
  7.     nil 
  8.   end 
  9. end 

本質(zhì)上,這將為每個(gè)對(duì)象添加方法 try。當(dāng) Object 是 nil 時(shí),try 只返回 nil。但 Object 不是 nil 時(shí),try 就調(diào)用當(dāng)前所用的方法。

使用 Ruby 開(kāi)放類(lèi)的目標(biāo)程序,結(jié)合 Ruby 中所有事物都是對(duì)象(包括 nil)這一事實(shí),我們就能夠創(chuàng)建新的 Ruby 功能。同樣,這沒(méi)有什么大不了的,不過(guò)是又一個(gè)示例:在語(yǔ)言中做出正確的選擇,我們就能夠創(chuàng)建有用的抽象。

#p#

10.  Rack

由于 Rack 不是 Ruby 語(yǔ)言的組成部分,所以這一點(diǎn)有點(diǎn)欺騙性。但是,它的確可以演示某些有用的功能。首先,今年早些時(shí)候,Rack 庫(kù)才發(fā)布 1.0,并且所有單個(gè) Ruby web 框架都已經(jīng)與 Rack 兼容。如果你使用 Ruby 框架,我保證你就可以使用 Rack,并且所有標(biāo)準(zhǔn)的 Rack 中間件也可以運(yùn)行。

做到這一點(diǎn)無(wú)需犧牲任何向后的兼容性,這也說(shuō)明了 Ruby 語(yǔ)言的靈活。Rack 本身也可以利用 Ruby 功能來(lái)完成工作。

Rack API 如下:

                 
                 
                 
  1. Rack::Builder.new do 
  2.   use Some::Middleware, param  
  3.   use Some::Other::Middleware  
  4.   run Application  
  5. end 

在這個(gè)簡(jiǎn)短的代碼片段中,包含了很多東西。首先,一個(gè)區(qū)塊被傳遞到 Rack::Builder。第二,該區(qū)塊在一個(gè)新的 Rack::Builder 實(shí)例(通過(guò)它可以訪(fǎng)問(wèn) use 和 run 方法)中進(jìn)行求值。第三,傳遞到 use 和 run 的參數(shù)是類(lèi)的名字,在 Ruby 中它是一個(gè)簡(jiǎn)單的對(duì)象。這樣,Rack 就能夠調(diào)用 passed_in_middleware.new(app, param),其中 new 是一個(gè)調(diào)用 Class 對(duì)象 Some::Middleware 的方法。

假如你認(rèn)為上面的實(shí)現(xiàn)可能會(huì)需要一堆你所憎惡的代碼,讓我們?cè)倏聪旅妫?/p>

                   
                   
                   
  1. class Rack::Builder  
  2.   def initialize(&block)  
  3.     @ins = []  
  4.     instance_eval(&block) if block_given?  
  5.   end 
  6.    
  7.   def use(middleware, *args, &block)  
  8.     @ins << lambda { |app| middleware.new(app, *args, &block) }  
  9.   end 
  10.    
  11.   def run(app)  
  12.     @ins << app #lambda { |nothing| app }  
  13.   end 
  14. end 

上面我演示創(chuàng)建了一個(gè)新的 Rack 程序,這里就是所需的所有代碼。對(duì)中間件鏈進(jìn)行實(shí)例化也很簡(jiǎn)單:

                     
                     
                     
  1. def to_app  
  2.   inner_app = @ins.last  
  3.   @ins[0...-1].reverse_each { |app| inner_app = app.call(inner_app) }  
  4.   inner_app  
  5. end 
  6.    
  7. def call(env)  
  8.   to_app.call(env)  
  9. end 

首先,我們從該鏈中取出***一個(gè)元素(末點(diǎn)),然后我們以相反的方向遍歷其余元素,使用鏈中的下一個(gè)元素對(duì)每個(gè)中間件進(jìn)行實(shí)例化,并返回結(jié)果對(duì)象。

***,我們?cè)?Builder 上定義了一個(gè)調(diào)用方法(Rack 尤其要求),它調(diào)用 to_app 并將環(huán)境傳遞過(guò)去,結(jié)束這個(gè)鏈。

通過(guò)本文中描述的這些技巧,利用幾十行的代碼,我們就能夠創(chuàng)建支持 Rack 中間件、兼容 Rack 的應(yīng)用程序。

原文:My 10 Favorite Things About the Ruby Language

作者:Yehuda Katz


網(wǎng)站題目:牛人點(diǎn)評(píng)Ruby語(yǔ)言十大令人喜愛(ài)的特點(diǎn)
分享網(wǎng)址:http://www.5511xx.com/article/djcdjsc.html