Ruby動態(tài)方法初探

1.方法的動態(tài)調(diào)用

為何Ruby如此先進(jìn),為何它元編程能力這么強(qiáng)大嘉蕾,得益于它能夠運(yùn)行時生成需要的代碼,或者調(diào)用相應(yīng)的方法霜旧。這樣的特性給Ruby程序增加了不少的靈活性错忱。(好了,我當(dāng)然知道Python也有類似的東西)這里我們看看Ruby是如何優(yōu)雅地動態(tài)調(diào)用方法挂据。

[1] pry(main)> class MyClass
[1] pry(main)*   def my_method(my_arg)
[1] pry(main)*     my_arg * 2
[1] pry(main)*   end
[1] pry(main)* end
=> nil
[2] pry(main)> obj = MyClass.new
=> #<MyClass:0x007fec79b94b10>
[3] pry(main)> obj.send(:my_method, 3)
=> 6

為了方便我就直接在pry交互環(huán)境里面定義一個類MyClass以清,并創(chuàng)建該類的一個對象obj。最后我們通過一個send方法來調(diào)用函數(shù)崎逃,而沒有用對象.方法 的方式來調(diào)用掷倔。這種調(diào)用函數(shù)的方式叫做動態(tài)指派
其實(shí)這種方式更加清晰說明調(diào)用方法的概念: 調(diào)用一個方法實(shí)際上就是給對象發(fā)送一條消息

這里可以看成我們給obj對象send一個消息my_method以及參數(shù)3个绍。

很多人可能有疑問勒葱,這里的:my_method是什么鬼。

這里得說一下巴柿,它是Ruby的內(nèi)置類型凛虽,叫做符號,它跟Ruby的字符串的用法其實(shí)是差不多的广恢。每個字符串都有它對應(yīng)的符號

[4] pry(main)> "lanzhiheng".class
=> String
[5] pry(main)> :lanzhiheng.class
=> Symbol
[10] pry(main)> "lanzhiheng".to_sym
=> :lanzhiheng
[11] pry(main)> :lanzhiheng.to_s
=> "lanzhiheng"

只是我們應(yīng)該還記得凯旋,Ruby里面字符串是可變的。而我們這里提到的符號是不可變的钉迷。因此符號更加適合表示方法名至非。當(dāng)然,這里用字符串來表示也是沒問題的糠聪。

[12] pry(main)> obj.send("my_method", 2)
=> 4

不過我們還是遵守社區(qū)的建議荒椭,用符號來表示這一類值吧,而且也有人說舰蟆,Ruby中使用符號會相比字符串更加節(jié)省空間趣惠,運(yùn)行速度會更快一些

2.動態(tài)方法的定義

這里不得不提到一個很優(yōu)雅的動態(tài)定義方法的語法夭苗, 這里我們就不偷懶了信卡,我在腳本上寫下面的邏輯。

class MyClass
  define_method :my_method do |my_arg|
    my_arg * 3
  end
end

obj = MyClass.new
p obj.my_method(3)

由運(yùn)行結(jié)果9可以看出我們的方法是定義成功了题造。這里的define_method方法能夠很方便地定義我們需要的方法傍菇。總的來說它接收兩個參數(shù), 1. 函數(shù)名界赔。2. 方法體(這里是通過代碼塊的方式定義的)

借助這種方式我們可以通過類似工廠的方式來產(chǎn)出許多方法名不同而它們的方法體卻有一定規(guī)律的方法丢习。在一定程度上牵触,減少了不必要的代碼量。如下:

["hello", "hi", "say"].each do |name|
  define_method "#{name}_define" do
    name
  end
end


p hello_define
p hi_define
p say_define

結(jié)果是:

"hello"
"hi"
"say"

之前還聽到有些同行吐槽說不喜歡Ruby的代碼塊咐低,說是不夠優(yōu)雅揽思,但是我是比較喜歡這種方式。不知道您怎么想见擦。-_-

3.幽靈方法

這里最最最得說一下的就是幽靈方法钉汗。
幽靈方法的方法名是method_missing,看名字就很霸氣鲤屡,它相當(dāng)于一個鉤子损痰。當(dāng)你調(diào)用的方法不存在的時候就會調(diào)用這個方法。舉個栗子看看酒来。

class MyClass
  def method_missing(method, *args)
    "The method #{method} with you call not exists"
  end
end

obj = MyClass.new
p obj.hello_world("becase")

打印的結(jié)果是

"The method hello_world with you call not exists"

這在正常情況下是會報錯的卢未,如今卻能夠利用幽靈方法給出那么優(yōu)雅的消息提示。
然而, 這種方式有什么用? 我們可以用幽靈方法來做一些東西堰汉。我舉個最簡單的例子辽社,當(dāng)然實(shí)際例子會復(fù)雜很多。

class Proxy
  def method_missing(method, *args)
    MyClass.send(method, *args)
  end
end

class MyClass
  def self.user
    "Ruby"
  end

  def self.password
    "RubyOnRails"
  end
end


proxy = Proxy.new
p proxy.user
p proxy.password

這里我們Proxy類對象的幽靈方法會調(diào)用MyClass類的類方法userand password翘鸭。這里如果我們MyClass添加新的方法滴铅,而我們需要利用Proxy類去訪問的話,則不需要修改Proxy類里面的任何代碼矮固。我們只需要像平常那樣去調(diào)用就行失息。幽靈方法會幫我們代理到MyClass那里去譬淳。這種方式稱作動態(tài)代理档址。這非常有助于我們編寫更加簡約的代碼。

不過上面這些奇怪的東西邻梆,多元化的編碼方式守伸,使得Ruby這門語言開發(fā)的項(xiàng)目相對于Python語言開發(fā)的項(xiàng)目門檻高了不少。不過這也是Ruby吸引人的地方不是嗎浦妄?

今天就到這里吧尼摹。

Happy Coding !!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市剂娄,隨后出現(xiàn)的幾起案子蠢涝,更是在濱河造成了極大的恐慌,老刑警劉巖阅懦,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件和二,死亡現(xiàn)場離奇詭異,居然都是意外死亡耳胎,警方通過查閱死者的電腦和手機(jī)惯吕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門惕它,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人废登,你說我怎么就攤上這事淹魄。” “怎么了堡距?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵甲锡,是天一觀的道長。 經(jīng)常有香客問我羽戒,道長搔体,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任半醉,我火速辦了婚禮疚俱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘缩多。我一直安慰自己呆奕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布衬吆。 她就那樣靜靜地躺著梁钾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪逊抡。 梳的紋絲不亂的頭發(fā)上姆泻,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機(jī)與錄音冒嫡,去河邊找鬼拇勃。 笑死,一個胖子當(dāng)著我的面吹牛孝凌,可吹牛的內(nèi)容都是我干的方咆。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼蟀架,長吁一口氣:“原來是場噩夢啊……” “哼瓣赂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起片拍,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤煌集,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后捌省,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體苫纤,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了方面。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片放钦。...
    茶點(diǎn)故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖恭金,靈堂內(nèi)的尸體忽然破棺而出操禀,到底是詐尸還是另有隱情,我是刑警寧澤横腿,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布颓屑,位于F島的核電站耿焊,受9級特大地震影響揪惦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜罗侯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一器腋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钩杰,春花似錦纫塌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至避除,卻和暖如春怎披,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瓶摆。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工凉逛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赏壹。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓鱼炒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蝌借。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理指蚁,服務(wù)發(fā)現(xiàn)菩佑,斷路器,智...
    卡卡羅2017閱讀 134,639評論 18 139
  • 在本教程中凝化,將探討使用Ruby開始編程所需的基本語法稍坯,以及如何在30分鐘內(nèi)快速入門學(xué)習(xí)并使用Ruby編程語言。 注...
    易百教程閱讀 7,192評論 1 36
  • 請把話筒轉(zhuǎn)交給我,對Ruby我有一些逼要裝瞧哟。 在Beansmile做前端已經(jīng)有半年多了混巧,這件四川特產(chǎn)我還留著。倒不...
    lanzhiheng閱讀 2,607評論 8 18
  • 一勤揩、異同對比選擇1咧党、Python和ruby的相同點(diǎn): * 都強(qiáng)調(diào)語法簡單,都具有更一般的表達(dá)方式陨亡。python是縮...
    沃倫蓋茨閱讀 4,139評論 2 24
  • 秋天傍衡,無論什么地方的秋天,在我看來都是好的负蠕。大概因?yàn)樯诰旁峦芄。愿悠珢矍锾欤参ㄓ星锛菊谔牵攀且荒曛凶钊侨诵木w...
    溪上青青草hh閱讀 621評論 0 3