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

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
初探RubyMetaprogramming

推薦專題:Ruby On Rails開發(fā)教程

延津網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),延津網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為延津1000多家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站制作要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的延津做網(wǎng)站的公司定做!

Classes are open

我們先看一段代碼:

 
 
 
  1. class String 
  2.   def say_hello  
  3.     p "Hello!" 
  4.   end 
  5. end 
  6.  
  7. "Fred".say_hello 

這里我們看到我們r(jià)eopen了String這個(gè)build-in的class,而且添加了一個(gè)新的方法say_hello(.NET 3.5中通過擴(kuò)展方法也實(shí)現(xiàn)了這個(gè)特性,但ruby的實(shí)現(xiàn)更加自然和靈活)這樣使得ruby語言自身提供了很大的可擴(kuò)展性,而這種從編程語言層面提供的可擴(kuò)展性為好處體現(xiàn)在兩個(gè)方面。

第一,對(duì)于ruby語言自身,在其以后的版本中可以對(duì)原有類在不破壞原有代碼的基礎(chǔ)之上提供更多更好的方法。.NET 3.5 已經(jīng)通過擴(kuò)展方法這個(gè)新特性,在原有集合類的方法之外增加了一些新的查詢方法。

第二,對(duì)于ruby的使用者,也就是我們這些ruby程序員來說。classes are open,這就意味我們可以更加實(shí)現(xiàn)我們一些具體的特殊的需求。例如,我們希望我們應(yīng)用的程序中的String都可以提供一個(gè)encrype的方法,來實(shí)現(xiàn)加密。又或者我們對(duì)于String類的to_s方法的實(shí)現(xiàn)覺得不夠滿意,我們都可以reopen String這個(gè)類,然后定義我們的方法。因?yàn)閞uby的方法查找遵循

”Define a method twice inside the same class, the second method definition takes precedence“

所有我們毋需擔(dān)心,我們對(duì)于to_s的調(diào)用出問題。

前面我說道,ruby的open class比.NET提供的擴(kuò)展方法更加靈活。而這個(gè)靈活體現(xiàn)在我們可以針對(duì)一個(gè)instance去增加方法,如下

 
 
 
  1. fred = 'fred' 
  2. def fred.say_hello  
  3.   p 'hello' 
  4. end 
  5.  
  6. fred.say_hello  
  7.  

這樣就滿足了我們對(duì)于一些特殊instance的需求。

Definition are active

 
 
 
  1. class Logger  
  2.   if ENV['debug']  
  3.     def log   
  4.       'debug' 
  5.     end 
  6.   else 
  7.     def log  
  8.       'non-debug' 
  9.     end 
  10.   end 
  11. end 

這是一段非常簡(jiǎn)單的代碼,但是我們可以看到我們是否定義debug這個(gè)ENV對(duì)于我們的程序會(huì)有完全不一樣的行為。這里也許有人會(huì)說靜態(tài)語言的條件編譯同樣能完成這樣的任務(wù)。那么我們就再看一段代碼

 
 
 
  1. result = class Fred  
  2.   puts 'Hello' 
  3.   x = 3  
  4. end 
  5.  
  6. puts result  
  7.  

執(zhí)行這段代碼,我們會(huì)看到這樣的輸出結(jié)果:

Hello 
3

為什么會(huì)輸出Hello呢?因?yàn)閐efinition are active,也就是定義本身就是一段可執(zhí)行的代碼。為什么會(huì)輸出3呢?因?yàn)閞uby中所有的可執(zhí)行代碼都會(huì)有返回值。到這里肯定會(huì)有人問,那么class定義中的method呢?你可以試試在irb中定義一個(gè)method,你會(huì)發(fā)現(xiàn)在irb會(huì)返回一個(gè)nil給你。

但是definition are active在我們實(shí)際開發(fā)中有什么用呢?那讓我們看一下一個(gè)rails的應(yīng)用

 
 
 
  1. module ActiveRecord  
  2.   class Base  
  3.     def has_many models  
  4.         
  5.     end 
  6.       
  7.     def belongs_to model  
  8.         
  9.     end 
  10.       
  11.   end 
  12. end 
  13.  
  14. class Order < ActiveRecord::Base  
  15.   has_many :items 
  16. end 
  17.  
  18. class Item < ActiveRecord::Base  
  19.   belongs_to :order 
  20. end 

你能想想如果definition aren't activity, 還會(huì)有這樣優(yōu)雅的代碼嗎?

All methods have a receiver

在ruby中,方法的調(diào)用是以message的形式發(fā)送給相應(yīng)的instance的。比如說foo.hello(),就是發(fā)送hello這個(gè)message給foo。這里很多人會(huì)好奇,那么如果我在irb上直接定義方法呢?其實(shí)ruby里面有一個(gè)概念叫top level execution, 它是一個(gè)Object的instance叫做main。當(dāng)你直接在irb中定義一個(gè)方法或者執(zhí)行一個(gè)方法(例如puts "hello"),同樣你只是發(fā)送了一個(gè)message,而這個(gè)message的receiver就是top level execution。

ruby代碼的執(zhí)行是與當(dāng)前代碼所在context相關(guān),不同的context關(guān)聯(lián)不同的receiver。也就是當(dāng)你的代碼在不同的context下執(zhí)行,由于context關(guān)聯(lián)的receiver不同也就有了不同的結(jié)果。

 
 
 
  1. class Context  
  2.   def name  
  3.     "smith" 
  4.   end     
  5.   p name      
  6.   def hi  
  7.     p name  
  8.   end 
  9. end  
  10. Context.new.hi 

結(jié)果為:

"Context"
 "smith"

如果你想知道在你當(dāng)前context下你方法的receiver,可以通過在當(dāng)前context下調(diào)用self來獲得。

Class are Object

我們都知道一個(gè)object有什么樣的行為和屬性是在ruby中由它的class決定。比如

 
 
 
  1. class Person  
  2.   attr_reader :name 
  3.     
  4.   def initialize(name)  
  5.     @name = name  
  6.   end 
  7.     
  8.   def introduce  
  9.     "I'm #{@name}." 
  10.   end 
  11. end 
  12.  
  13. p = Person.new "Dave" 

對(duì)于這個(gè)例子中,p具有什么樣的行為和屬性是由Person這個(gè)class決定的。可是我們看到對(duì)于Person我們調(diào)用了一個(gè)new的方法,那么這個(gè)new方法是由誰定義的呢?很簡(jiǎn)單啊,我們知道p的行為和屬性由它的class也就是Person決定,那么Person的new方法應(yīng)該也來自它的class。也就是引出了Class對(duì)象,Class對(duì)象中有兩個(gè)new方法,一個(gè)是class method另一個(gè)是instance method。我們的Person.new自然調(diào)用的就是Class對(duì)象中叫new的instance method, 那么那個(gè)叫做new的class method有什么用呢?

 
 
 
  1. Person = Class.new do 
  2.   attr_reader :name 
  3.     
  4.   def initialize(name)  
  5.     @name = name  
  6.   end 
  7.     
  8.   def introduce  
  9.     "I'm #{@name}." 
  10.   end 
  11. end 

這段代碼可以實(shí)現(xiàn)之前那段代碼一摸一樣的功能,而這里調(diào)用的就是Class中叫做new的class method。最奇怪的Class的superclass是Module,而Module的superclass是Object,但是Class的class是自身,Module的class是Class,而Object的class也是Class(superclass是Class的方法,class是Object的方法),我們也可以說ruby中所有的Object的class都是Class(nil的class是NilClass,但是NilClass的class是Class)。Class間接繼承Object,但是Object的class又是Class,一個(gè)典型“雞生蛋,蛋生雞”的問題。這個(gè)問題給我最大困惑則是:如果我調(diào)用一個(gè)對(duì)象例如上面例子中p的XX方法,而這個(gè)XX方法并沒有直接在Person中定義,那么這個(gè)XX方法是來自Class還是Object呢?而對(duì)于這一點(diǎn)ruby的解決辦法是在方法的查找receiver的時(shí)候,會(huì)先檢查Person有沒有這個(gè)XX方法,會(huì)先檢查Class后檢查Object,也就是先檢查一個(gè)class的class,然后檢查superclass。
 

原文鏈接:http://www.cnblogs.com/feihe/archive/2011/04/17/1951274.html

【編輯推薦】

  1. 關(guān)于Ruby/RoR我的體驗(yàn)和看法
  2. 橫向壓力測(cè)試:Ruby on Rails PK CakePHP
  3. 在Nginx上運(yùn)行Ruby on Rails
  4. 解讀Ruby on Rails的成功秘籍
  5. 加速Ruby on Rails 消除N+1查詢問題

網(wǎng)站欄目:初探RubyMetaprogramming
網(wǎng)站URL:http://www.5511xx.com/article/cdopsig.html