亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪(fǎng)問(wèn)板塊 發(fā)新帖
查看: 17417 | 回復(fù): 2
打印 上一主題 下一主題

嘎嘎叫的小狗——快樂(lè)的鴨子類(lèi)型 [復(fù)制鏈接]

論壇徽章:
2
2015年辭舊歲徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:55:28
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2013-08-23 09:32 |只看該作者 |倒序?yàn)g覽
  

  
鴨子類(lèi)型是我目前在Ruby語(yǔ)言里最喜歡的一個(gè)“功能特征”,主要是因?yàn)樗茏屛覀冚p松的寫(xiě)出漂亮的代碼——畢竟,你無(wú)需再擔(dān)心類(lèi)型:你可以把精力全部集中到你想發(fā)送的消息上,以及你需要打交道的對(duì)象能發(fā)揮的功能上。

我第一次接觸Ruby時(shí)就知道它是一種“鴨子類(lèi)型語(yǔ)言”,但我的靜態(tài)編譯型語(yǔ)言的背景知識(shí)妨礙了我真正理解鴨子類(lèi)型的真正含義。理論很簡(jiǎn)單:如果你設(shè)計(jì)一個(gè)方法,它需要一個(gè)‘鴨子’參數(shù),那么你呼叫一聲“嘎嘎”,任何以“嘎嘎”回應(yīng)你的對(duì)象都可以傳入這個(gè)方法——這個(gè)對(duì)象究竟是什么類(lèi)型并不重要。很顯然,你可以得出這樣的結(jié)論,如果你寫(xiě)出一個(gè)Dog類(lèi),它實(shí)現(xiàn)了一個(gè)叫“嘎嘎”的方法(很奇怪的狗),那么,你可以把這個(gè)狗傳入上面的那個(gè)方法,一點(diǎn)問(wèn)題都沒(méi)有。非常酷吧,鴨子類(lèi)型的強(qiáng)大功能震撼了我,我認(rèn)識(shí)到,它在各種對(duì)象間打通了一條重要的溝通途徑,強(qiáng)化了API的能力,減少了代碼中的干擾。為了說(shuō)明這些,讓我來(lái)展示一些Ruby標(biāo)準(zhǔn)庫(kù)中的幾個(gè)例子。
File.open
File.open(“path/to/file&rdquo最常見(jiàn)的讀取文件的方法:你傳入path,這個(gè)方法會(huì)返回一個(gè)能讀取文件的對(duì)象。你是否注意到,我加粗強(qiáng)調(diào)了“path”這個(gè)詞。這是特意的——這個(gè)‘open’函數(shù)實(shí)際可以接受任何可以扮演路徑角色的東西,并不僅僅指路徑字符串。這區(qū)別有些微妙,但你會(huì)發(fā)現(xiàn)我們可以把代碼這樣寫(xiě):

class VimConfig
  # ... behavior ... #        
  def to_path
    "~/.vimrc"
  end
end
config = VimConfig.new
config_file = File.open config
   很帥,不是嗎?Ruby的File API在使用它的參數(shù)前會(huì)進(jìn)行轉(zhuǎn)化,轉(zhuǎn)化的一種途徑是通過(guò)‘to_path’方法。如果你感到奇怪,下面是實(shí)現(xiàn)它的C語(yǔ)言代碼(‘rb_f_open’ 調(diào)用 ‘FilePathValue’,后者最終調(diào)用 ‘rb_get_path_check_to_string&rsquo):

static VALUE
rb_f_open(int argc, VALUE *argv)
{
    ID to_open = 0;
    int redirect = FALSE;
    if (argc >= 1) {
  CONST_ID(to_open, "to_open";
        if (rb_respond_to(argv[0], to_open)) {
            redirect = TRUE;
        }
        else {
            VALUE tmp = argv[0];
            FilePathValue(tmp);
            if (NIL_P(tmp)) {
                redirect = TRUE;
            }
            else {
                VALUE cmd = check_pipe_command(tmp);
                if (!NIL_P(cmd)) {
                    argv[0] = cmd;
                    return rb_io_s_popen(argc, argv, rb_cIO);
                }
            }
        }
    }
    if (redirect) {
        VALUE io = rb_funcall2(argv[0], to_open, argc-1, argv+1);
        if (rb_block_given_p()) {
            return rb_ensure(rb_yield, io, io_close, io);
        }
        return io;
    }
    return rb_io_s_open(argc, argv, rb_cFile);
}
VALUE
rb_get_path_check_to_string(VALUE obj, int level)
{
    VALUE tmp;
    ID to_path;
    if (insecure_obj_p(obj, level)) {
        rb_insecure_operation();
    }
    if (RB_TYPE_P(obj, T_STRING)) {
        return obj;
    }
    CONST_ID(to_path, "to_path";
    //to_path call!
    tmp = rb_check_funcall(obj, to_path, 0, 0);
    if (tmp == Qundef) {
        tmp = obj;
    }
    StringValue(tmp);
    return tmp;
}
數(shù)組索引
數(shù)組索引(a_array[index])是另外一個(gè)很好的例子:它會(huì)向索引調(diào)用‘to_int’方法,所以,任何能響應(yīng)to_int方法的對(duì)象都可以當(dāng)作索引。這讓我們可以這樣寫(xiě):
class PodiumPosition
  # .. behavior .. #
  def to_int
    @race_position
  end
end
position = PodiumPosition.new(1)
prizes = [ "orange", "apple", "corn" ]
puts "Congrats, you won #{prizes[position]}"
IO.select
我是通過(guò)IO.select API才第一次發(fā)現(xiàn)了Ruby的強(qiáng)大。這個(gè)API會(huì)調(diào)用系統(tǒng)select(2)函數(shù),接收文件描述符參數(shù),并掛起當(dāng)前的線(xiàn)程,直到有文件可以進(jìn)行讀寫(xiě)操作。這個(gè)Ruby函數(shù)定義如下:
select(read_array
        [, write_array
        [, error_array
        [, timeout]]]) → array or nil
因此,你可以傳入一個(gè)數(shù)據(jù)流數(shù)組,而“select”函數(shù)會(huì)一直等到流文件準(zhǔn)備好可讀或可寫(xiě)。問(wèn)題是,很多數(shù)據(jù)流是存儲(chǔ)在具有各種行為特征的特定對(duì)象里的(例如一個(gè)執(zhí)行網(wǎng)絡(luò)操作的Connection類(lèi)),這些對(duì)象里的IO接口通常經(jīng)過(guò)了二次封裝,外界無(wú)法直接訪(fǎng)問(wèn)。根本不可能通過(guò)重構(gòu)內(nèi)核代碼來(lái)適應(yīng)‘select’ API。打破它的封裝嗎?很顯然不行!這時(shí)‘to_io’方法就成了救星!
class Connection
  # .. rest of the class .. #
  def accept_connection(io)
    @io = io
    # new connection code
  end
  def to_io
    @io
  end
end
class Reactor
  # array_of_connections_to_read is an array of instances of the above Connection class
  # array_of_connections_to_write is an array of instances of the above Connection class
  def tick
    to_read, to_write = IO.select(array_of_connections_to_read, array_of_connections_to_write)
  end
end
你可以看到,Ruby的標(biāo)準(zhǔn)庫(kù)里到處都是鴨子類(lèi)型

.
重構(gòu)
最明顯,也是最值得一提的鴨子類(lèi)型的好處是,它讓重構(gòu)變得更容易:“用多型替換條件判斷”和 “Replace Type Code with Strategy/State”的重構(gòu)原則,當(dāng)你不需要考慮類(lèi)型、只關(guān)心行為時(shí),這些都變得極其簡(jiǎn)單和容易實(shí)現(xiàn)。

鴨子類(lèi)型的黑暗面
沒(méi)有編譯器為你探路是很危險(xiǎn)的。專(zhuān)業(yè)的Ruby程序員(1)永遠(yuǎn)不會(huì)忘記有責(zé)任測(cè)試它們的代碼的各種行為,并且(2)一定寫(xiě)出整潔的代碼,并及時(shí)重構(gòu)。Ruby代碼必須要認(rèn)真寫(xiě),否者調(diào)試起來(lái)就會(huì)是一場(chǎng)噩夢(mèng)。

同時(shí),動(dòng)態(tài)語(yǔ)言一般最合適的是開(kāi)發(fā)小型或中型軟件。我的經(jīng)驗(yàn)告訴我,當(dāng)系統(tǒng)變得復(fù)雜時(shí),最好把它拆分成小的應(yīng)用,如果是用動(dòng)態(tài)語(yǔ)言開(kāi)發(fā)的,那這種做法更加重要——一個(gè)reddit的網(wǎng)友說(shuō)需要在一個(gè)10萬(wàn)行的程序了修改一個(gè)函數(shù)的名稱(chēng),我只能說(shuō),這很難實(shí)現(xiàn)。修改公開(kāi)的接口,這很難很難。有時(shí)最好把它標(biāo)注為‘廢棄’就行了。

結(jié)論
動(dòng)態(tài)語(yǔ)言能漂亮的解決你的問(wèn)題,但需要有很好的設(shè)計(jì),Ruby的標(biāo)準(zhǔn)庫(kù)里鴨子類(lèi)型為我們提供了方便的途徑。它是一個(gè)很好的例子,向我們展示了一個(gè)Ruby程序員該如何的編程:按對(duì)象的行為——而不是按對(duì)象的類(lèi)型——來(lái)接收參數(shù)。

我希望這篇文章給那些仍然不明白像Ruby這樣的語(yǔ)言的強(qiáng)大之處的人帶來(lái)新的認(rèn)識(shí)。我推薦閱讀下面幾本書(shū)來(lái)進(jìn)一步的學(xué)習(xí):

[英文原文:Quacking The Dog - Duck typing for happiness]

轉(zhuǎn)自:http://www.aqee.net/quacking-the-dog-duck-typing-for-happiness/


本文來(lái)自ChinaUnix新聞?lì)l道,如果查看原文請(qǐng)點(diǎn):http://news.chinaunix.net/opensource/2013/0823/2907892.shtml

論壇徽章:
7
戌狗
日期:2013-12-15 20:43:38技術(shù)圖書(shū)徽章
日期:2014-03-05 01:33:12技術(shù)圖書(shū)徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16賽季CBA聯(lián)賽之青島
日期:2016-03-17 20:36:13
2 [報(bào)告]
發(fā)表于 2013-08-29 04:23 |只看該作者
這就非?崃恕。

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2013-10-05 13:51 |只看該作者
這鴨子類(lèi)型
有些微妙
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專(zhuān)區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP