日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

深入理解alias, alias_method和alias_method_chain

發(fā)布時(shí)間:2023/12/4 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解alias, alias_method和alias_method_chain 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
對(duì)于alias, alias_method, alias_method_chain的深入理解是有益的,因?yàn)閞ails3的源碼里很多地方使用了alias_method_chain的魔法。 有人評(píng)論說(shuō)alias_method_chain使用的過(guò)多不好,具體怎么不好,是后話了,這篇文章集中在理解這3個(gè)方法上面。

如果想轉(zhuǎn)載本文,請(qǐng)注明出處,謝謝!請(qǐng)尊重別人的勞動(dòng)成果,為構(gòu)建豐富web原創(chuàng)內(nèi)容做貢獻(xiàn)!


1. alias
?? Ruby里的關(guān)鍵字,用于定義方法或者全局變量的別名。 例子:
?? class A
???? def m1
?????? puts "m1"
???? end
???? alias m2 m1
??? end
=> nil
a = A.new
=> #<A:0xb7ef5234>
?a.m1
m1
=> nil
a.m2
m1
=> nil

在使用的時(shí)候,注意原有的方法名在最后位置,用空格分開(kāi)。

2. alias_method
作用和alias差不多,是Module的一個(gè)私有實(shí)例方法,只能用于給方法起別名,并且參數(shù)只能是字符串或者符號(hào)(alias后面跟的直接是方法名,不是字符串也不是符號(hào))。例子:
class B
? def b
??? p "b"
? end
? alias_method :c, :b
end
=> B
b = B.new
=> #<B:0xb7ee75bc>
b.c
"b"
=> nil
b.b
"b"
=> nil
注意,alias_method的參數(shù)必須是字符串或者是符號(hào),并且用逗號(hào)分隔。

3. alias_method_chain
是ActiveSupport的一個(gè)公有實(shí)例方法。同樣接受兩個(gè)參數(shù),可以是符號(hào),也可以是字符串,但要注意一下第1個(gè)參數(shù)才是原始方法(alias_method的第2個(gè)參數(shù)是原始方法)。例子:
class A
? def m1
??? puts 'm1'
? end
? def m1_with_m2
??? puts "do something befor m1"
??? m1_without_m2
??? puts "do something after m2"
? end
? alias_method_chain :m1, :m2
end
=> A
a = A.new
=> #<A:0xb7bd9820>
a.m1
do something befor m1
m1
do something after m2
=> nil

上面的代碼用alias或者alias_method也能完成:
class A ?
? def m1 ?
??? puts 'm1' ?
? end
? alias m1_without_m2 m1 ?
? def m1_with_m2 ?
??? puts 'do something else' ?
??? m1_without_m2 ?
? end ?
? alias m1 m1_with_m2 ?
end

那么其原理也一目了然了:
a = A.new
a.m1
當(dāng)調(diào)用m1的時(shí)候, m1_with_m2會(huì)執(zhí)行,? 在puts "do something befor m1"之后,執(zhí)行m1_without_m2,這個(gè)時(shí)候是執(zhí)行了真正的m1方法。 這樣就形成了一個(gè)類似于AOP的行為。
也可以說(shuō),對(duì)外把m1方法隱藏起來(lái)了,對(duì)類外部,實(shí)際上把m1_with_m2改頭換面已經(jīng)成為了另一個(gè)方法,只是我們不知道而已,因?yàn)樗€叫m1.

再來(lái)看看alias_method_chain的源碼:
def alias_method_chain(target, feature)?
? # Strip out punctuation on predicates or bang methods since?
? # e.g. target?_without_feature is not a valid method name.?
? aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1?
? yield(aliased_target, punctuation) if block_given???????
? with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}"?
? alias_method without_method, target?
? alias_method target, with_method???????
? case?
??? when public_method_defined?(without_method)?
????? public target?
??? when protected_method_defined?(without_method)?
????? protected target?
??? when private_method_defined?(without_method)?
????? private target?
? end?
end
一個(gè)道理。

更實(shí)際的例子:
在一些rails比較老的系統(tǒng)里,搜索功能的日期選擇可能會(huì)用到date_select,這個(gè)方法會(huì)生成類似于這樣的頁(yè)面元素:
search_form[start_from(1i)]年
search_form[start_from(2i)]月
search_form[start_from(3i)]日
把這樣的參數(shù)傳回去,就無(wú)法查詢到對(duì)應(yīng)的日期。這個(gè)時(shí)候我們需要在后臺(tái)得到查詢條件之后來(lái)處理日期,比如:
get_conditions 這個(gè)方法假如是得到頁(yè)面查詢條件的,它返回一個(gè)數(shù)組,這個(gè)時(shí)候我們可以定義:

def get_conditions_with_handle_date
? puts "你可以在get_conditions方法執(zhí)行前干點(diǎn)別的,如果你愿意"
? get_conditions_without_handle_date
? puts "get_conditions執(zhí)行完了,我們可以在其后干點(diǎn)別的,比如說(shuō)處理日期"
? conditions.reject!{|condition|condition[0] =~ /\([1-3]i\)/}?? # 把條件數(shù)組里的1i,2i,3i之類的去掉。
? conditions << ["? <= #{@model.table_name}.created_at", @search.start_from] if @search.start_from? #給搜索對(duì)象里添加正確的查詢?nèi)掌跅l件
? conditions << ["#{@model.table_name}.created_at < ?", @search.end_to + 1.day] if @search.end_to?? #給搜索對(duì)象里添加正確的查詢?nèi)掌跅l件
end
? #然后實(shí)施魔法
? alias_method_chain :get_conditions, :handle_date

這樣我們就搞定了。 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的深入理解alias, alias_method和alias_method_chain的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。