欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Ruby和元編程之萬(wàn)物皆為對(duì)象

 更新時(shí)間:2014年10月27日 11:18:49   投稿:junjie  
這篇文章主要介紹了Ruby和元編程之萬(wàn)物皆為對(duì)象,想要掌握Ruby和Ruby的元編程,對(duì)象就是第一門(mén)必修功課,需要的朋友可以參考下

開(kāi)篇

空即是色,色即是空。
空空色色,色色空空,在Ruby語(yǔ)言中,萬(wàn)物皆為對(duì)象。

Ruby是一個(gè)面向?qū)ο蟮恼Z(yǔ)言(Object Oriented Language),面向?qū)ο蟮母拍畋绕渌Z(yǔ)言要貫徹的堅(jiān)定很多。

Ruby中不存在Java中原始類(lèi)型數(shù)據(jù)和對(duì)象類(lèi)型數(shù)據(jù)之分。大部分Ruby中的的東東都是對(duì)象。

所以,想要掌握Ruby和Ruby的元編程,對(duì)象就是第一門(mén)必修功課。本回就著重研究一下Ruby中的對(duì)象.

Ruby中的對(duì)象

如果你從其他面向?qū)ο蟮恼Z(yǔ)言轉(zhuǎn)來(lái),一提到得到一個(gè)對(duì)象你可能會(huì)想到建立一個(gè)類(lèi),然后建立這個(gè)類(lèi)的實(shí)例出來(lái)產(chǎn)生一個(gè)對(duì)象。

在Ruby中這完全是可以的,不過(guò)這種先建立類(lèi)才能獲得對(duì)象的過(guò)程,聽(tīng)起來(lái)更像是面向類(lèi)的設(shè)計(jì),而不是面向?qū)ο蟮脑O(shè)計(jì)。關(guān)于類(lèi)的一些東西放到下回再說(shuō)。

在Ruby中,不存在原始類(lèi)型的概念,1, 0.3, true/false 甚至 nil都是對(duì)象。比如,你可以在irb中嘗試下面的代碼:

復(fù)制代碼 代碼如下:

>> 1.methods
=> ["%", "odd?", "inspect", "prec_i", "<<", "tap", "div", "&", "clone", ">>", "public_methods", "__send__", "instance_variable_defined?", "equal?", "freeze", "to_sym", "*", "ord", "lcm", "+", "extend", "next", "power!", "send", "round", "methods", <…more methods…> "is_a?", "ceil", "[]"]
>> 1.class
=> Fixnum

你可以在irb中嘗試一下其他數(shù)據(jù)類(lèi)型,看看他們的方法和類(lèi)等等信息。

不只是各種數(shù)據(jù)類(lèi)型,方法在Ruby中也是對(duì)象, 比如下列例子:

復(fù)制代碼 代碼如下:

>> one_plus = 1.method(:+)
=> #<Method: Fixnum#+>
>> one_plus.class
=> Method
>> one_plus.call(2)
=> 3

有意思的是,方法對(duì)象也是有方法的:

復(fù)制代碼 代碼如下:

>> one_plus.arity()
=> 1

對(duì)象到底是什么?

到底什么是對(duì)象呢?

簡(jiǎn)單的說(shuō),**對(duì)象就是 狀態(tài) + 行為**

狀態(tài) 就是表明當(dāng)前對(duì)象所擁有的屬性,每個(gè)同類(lèi)的對(duì)象可能有不同的狀態(tài),這些狀態(tài)保存在實(shí)例變量里面(Instance Variable).

對(duì)象的實(shí)例變量可以由instance_variable_set/instance_variable_get來(lái)設(shè)定/讀取:

復(fù)制代碼 代碼如下:

>> 1.instance_variable_set(:@my_var, "world")
=> "world"
>> 1.instance_variable_get(:@my_var)
=> "world"

行為 行為就是作用在對(duì)象上的動(dòng)作,就是我們常說(shuō)的方法。Ruby方法的調(diào)用,類(lèi)似于smalltalk或者Objectiv-C,采用消息模式。調(diào)用方法相當(dāng)于對(duì)這個(gè)對(duì)象發(fā)送了一個(gè)消息。所以對(duì)方法的調(diào)用也可以這樣:

在Ruby中,狀態(tài),也就是實(shí)例變量是保存在對(duì)象里的,而行為或方法則是存在于對(duì)象的類(lèi)或者mixin的module里面。

在靜態(tài)語(yǔ)言中,編譯時(shí)就會(huì)確定所調(diào)用的方法是否存在,不存在會(huì)產(chǎn)生編譯錯(cuò)誤。

Ruby中,當(dāng)我們?cè)诜椒ㄕ{(diào)用的運(yùn)行時(shí),對(duì)象會(huì)查找他隸屬的類(lèi),module,父類(lèi)等,來(lái)找到相對(duì)應(yīng)的方法。

Singleton/Meta/Anonymous/Ghost/Shadow Class

1.Singleton Class: 單例類(lèi)
2.Meta Class:元類(lèi)
3.Anonymous Class: 匿名類(lèi)
4.Ghost Class:鬼類(lèi)
5.Shadow Class: 影子類(lèi)

上面的這些東東其實(shí)說(shuō)的都是一個(gè)東西,我喜歡叫它 影子類(lèi)。

Ruby中每一個(gè)對(duì)象都一個(gè)一個(gè)影子類(lèi),這個(gè)影子類(lèi)存在于對(duì)象跟它所屬的類(lèi)之間:

對(duì)象("obj1") -> 影子類(lèi) -> 對(duì)象所屬的類(lèi)(String)

當(dāng)一個(gè)對(duì)象的方法被調(diào)用時(shí),首先查找的是影子類(lèi),之后才是它所屬的類(lèi)。

上面講到實(shí)例變量存在于對(duì)象內(nèi),方法存在于對(duì)象的類(lèi)中。
影子類(lèi)上的方法,就是只有這一個(gè)對(duì)象擁有的方法。這個(gè)方法通常叫做單例方法(Singleton Method)。

這樣的方法只存在于這個(gè)對(duì)象上,同一個(gè)類(lèi)的其他對(duì)象沒(méi)有這個(gè)方法,因?yàn)樗麄兊挠白宇?lèi)不同,其他對(duì)象的影子類(lèi)上沒(méi)有這個(gè)方法。

復(fù)制代碼 代碼如下:

>> a = "obj1"
=> "obj1"
>> def a.hello
>> puts "hello world"
>> end
=> nil
>> a.hello
hello world
=> nil
>> b = "obj2"
=> "obj2"
>> b.hello
NoMethodError: undefined method `hello' for "obj2":String
    from (irb):49
>> a.singleton_methods
=> ["hello"]
>> b.singleton_methods
=> []

Self

Ruby里面一切都是對(duì)象,self也是對(duì)象,確切地說(shuō)是當(dāng)前對(duì)象的引用。

前文說(shuō)Ruby的方法調(diào)用是消息模式,比如obj.method, 消息的接受者是.之前的對(duì)象,.之后的是方法及參數(shù)。
如果對(duì)象和.沒(méi)有出現(xiàn)的話(huà),消息會(huì)被默認(rèn)送到self對(duì)象。除了作為方法的默認(rèn)接受者,self也是實(shí)例變量的解析對(duì)象。

self在ruby一開(kāi)始的時(shí)候,被設(shè)定為一個(gè)叫做main的對(duì)象,再irb里面可以看到:

復(fù)制代碼 代碼如下:

>> m = self
=> main

self可以被認(rèn)為是一個(gè)特殊的變量,它的特殊性在于,你不能給他賦值:
復(fù)制代碼 代碼如下:

>> self = "obj"
SyntaxError: compile error
(irb):77: Can't change the value of self
self = "obj"
      ^

有幾個(gè)辦法可以改變self的值,.(obj.method的.)是其中一個(gè),除了.還有class/module關(guān)鍵字。
本回主要關(guān)注跟對(duì)象相關(guān)的.

當(dāng)我們用obj.method調(diào)用方法時(shí),接下來(lái)的時(shí)間代碼的執(zhí)行就會(huì)到相應(yīng)的方法里,運(yùn)行的上下文切換到那個(gè)對(duì)象,self自然也變成了那個(gè)對(duì)象。用def定義單例方法時(shí),道理也是相通的。 下面的例子可以說(shuō)明這個(gè)self切換的情況。

復(fù)制代碼 代碼如下:

>> a = "obj"
=> "obj"
>> def a.hello_self
>> puts "hello #{self}"
>> end
>> m = self
=> main
>> a.hello_self
hello obj

對(duì)象的復(fù)制

前文說(shuō)對(duì)象的存在包括兩部分,一是狀態(tài)/實(shí)例變量,另一個(gè)是行為,本回專(zhuān)注講了單例方法和影子類(lèi)。
Ruby中對(duì)象的復(fù)制也有兩種模式,一個(gè)是只復(fù)制當(dāng)前的狀態(tài)/實(shí)例變量 dup。另外一種是連同影子類(lèi)和引用的對(duì)象一起復(fù)制,從而把單例方法也復(fù)制一份。

復(fù)制代碼 代碼如下:

>> a = "obj"
>> def a.hello_self
>> puts "hello #{self}"
>> end
>> b = a.dup
=> "obj"
>> b.hello_self
NoMethodError: undefined method `hello_self' for "obj":String
    from (irb):90
>> b = a.clone
=> "obj"
>> b.hello_self
hello obj

其實(shí)有本回上述的這些功能,即便是沒(méi)有class,Ruby也可以作為一種Prototype(類(lèi)似JavaScript)的面向?qū)ο笳Z(yǔ)言了。

你可以建立一個(gè)對(duì)象,生成默認(rèn)的實(shí)例變量,把行為作為單例方法定以在這個(gè)對(duì)象的影子類(lèi)上,然后用clone生成千千萬(wàn)萬(wàn)個(gè)實(shí)例。當(dāng)然這樣比較麻煩,但卻是可行的途徑之一。

其他Object API

對(duì)象還有很多其他的功能,比如可以freeze,另外dup跟clone也有一些其他的引用上面的區(qū)別,dup只復(fù)制引用,clone會(huì)吧引用的對(duì)象也復(fù)制。

這些都可以在Object類(lèi)(Ruby所有對(duì)象的父類(lèi))API上找到,可以查看apidock.com的文檔

例如關(guān)于dup

.dup() produces a shallow copy of obj—the instance variables of obj are copied, but not the objects they reference. dup copies the tainted state of obj. See also the discussion under Object#clone. In general, clone and dup may have different semantics in descendant classes. While clone is used to duplicate an object, including its internal state, dup typically uses the class of the descendant object to create the new instance.

本回完

本回講了些對(duì)象相關(guān)的東西,有的很基礎(chǔ),有的是Ruby自身的一些特性。

其中Ruby對(duì)象模型中最具特色的兩個(gè)特性就是影子類(lèi)/單例方法和self,最好能深入理解這兩個(gè)概念。

且聽(tīng)下回分解

下回注重一些關(guān)于類(lèi)的故事。

相關(guān)文章

  • Ruby的XML格式數(shù)據(jù)解析庫(kù)Nokogiri的使用進(jìn)階

    Ruby的XML格式數(shù)據(jù)解析庫(kù)Nokogiri的使用進(jìn)階

    這篇文章主要介紹了Ruby的XML格式數(shù)據(jù)解析庫(kù)Nokogiri的使用進(jìn)階,文中對(duì)其從HTML/XML中抓取字段還有特別是命名空間的用法進(jìn)行了深入講解,需要的朋友可以參考下
    2016-04-04
  • Ruby字符串、條件、循環(huán)、數(shù)組、Hash、類(lèi)基本操作筆記

    Ruby字符串、條件、循環(huán)、數(shù)組、Hash、類(lèi)基本操作筆記

    這篇文章主要介紹了Ruby字符串、條件、循環(huán)、數(shù)組、Hash、類(lèi)基本操作筆記,需要的朋友可以參考下
    2014-06-06
  • Ruby中的String對(duì)象學(xué)習(xí)筆記

    Ruby中的String對(duì)象學(xué)習(xí)筆記

    這篇文章主要介紹了Ruby中的String對(duì)象學(xué)習(xí)筆記,本文講解了String對(duì)象的定義、String對(duì)象的操作、使用數(shù)組下標(biāo)的方式操作字符串等內(nèi)容,需要的朋友可以參考下
    2014-11-11
  • ruby中的雙等號(hào)==問(wèn)題詳解

    ruby中的雙等號(hào)==問(wèn)題詳解

    Ruby里面有4種比較方法,equal?, eql?, ==, ===,而且在不同的類(lèi)里面表現(xiàn)的很不一樣。在使用的時(shí)候也特別容易搞糊涂。 本文先給大家講述一下==號(hào)的用法及使用中應(yīng)該注意的地方
    2016-02-02
  • ruby實(shí)現(xiàn)github第三方認(rèn)證

    ruby實(shí)現(xiàn)github第三方認(rèn)證

    GitHub在用戶(hù)認(rèn)證過(guò)程中采用了雙匙機(jī)制,在雙匙加密機(jī)制中,只有合法用戶(hù)才擁有私匙,只要GitHub在收到請(qǐng)求時(shí)可以證明提交請(qǐng)求的客戶(hù)端上擁有該私匙,即可以確認(rèn)該操作是由合法用戶(hù)發(fā)起的。我們通過(guò)ruby來(lái)簡(jiǎn)單模擬下吧。
    2015-06-06
  • 源代碼快速定位工具-qwandry使用指南

    源代碼快速定位工具-qwandry使用指南

    qwandry是一款能快速定位到我們需要找到庫(kù)文件、項(xiàng)目的工具。是一個(gè)快速打開(kāi)我們指定文件夾的工具,比如快速打開(kāi)rails, activerecord等目錄。
    2014-07-07
  • Ruby與Ruby on Rails框架環(huán)境搭建的簡(jiǎn)明教程

    Ruby與Ruby on Rails框架環(huán)境搭建的簡(jiǎn)明教程

    這篇文章主要介紹了Ruby與Ruby on Rails框架環(huán)境搭建的簡(jiǎn)明教程,包括RubyGems的升級(jí)與OpenSSL的支持等配置,需要的朋友可以參考下
    2016-05-05
  • 在Ruby on Rails上使用Redis Store的方法

    在Ruby on Rails上使用Redis Store的方法

    這篇文章主要介紹了在Ruby on Rails上使用Redis Store的方法,是Ruby程序和Redis數(shù)據(jù)庫(kù)結(jié)合的有效途徑,需要的朋友可以參考下
    2015-06-06
  • 優(yōu)化Ruby腳本效率實(shí)例分享

    優(yōu)化Ruby腳本效率實(shí)例分享

    以前寫(xiě)過(guò)批量修改繁體文件名為簡(jiǎn)體的Ruby腳本 ,可惜腳本的性能很有問(wèn)題,批量重命名時(shí)運(yùn)行速度非常慢。這次準(zhǔn)備優(yōu)化下代碼,提升腳本的執(zhí)行效率。
    2014-06-06
  • 在阿里云 (aliyun) 服務(wù)器上搭建Ruby On Rails環(huán)境

    在阿里云 (aliyun) 服務(wù)器上搭建Ruby On Rails環(huán)境

    最近總是在配置阿里云的服務(wù)器,遇到不少問(wèn)題,現(xiàn)小結(jié)一下,供大家參考~~
    2014-06-06

最新評(píng)論