文斯雜談凸^-^凸

何かの犠牲なしに何も得ることができない、
何かを得るためには同等の代価が必要になる。
            --「鋼の錬金術士」

Jack是不是管理員?

  要問Jack是不是管理員,代碼一般有三種寫法。

php
1
if is_admin(Jack){ echo "Hi, Jack!"; }
java
1
if (Jack.is_admin()){ System.out.println("Hi, Jack!"); }
ruby
1
puts "Hi, Jack!" if Jack.admin?

  以上三種方法只有ruby的最一目瞭然,不會看花眼,最接近人的語言習慣。
  去除了繁雜的括號、花括號,行文直截了當,寫代碼就像寫文章一樣,甚至連寫註釋的功夫的省去了。
  更神奇的admin?這個方法根據ruby的動態特性可以在程序運行的時候才生成,而不需要預先寫好代碼。
  以下是我rails項目中的代碼片段:

實際代碼片段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def method_missing(method_id, *arguments, &block)
  if method_id.match(/^can_.*\?$/)
    something = method_id[4..-2]
    if something.blank?
      super(method_id, *arguments, &block)
    else
      self.class_eval <<-METHOD, __FILE__, __LINE__ + 1
        def #{method_id}
          self.can_do?(:sub_action => %{#{something}})
        end
      METHOD
      send(method_id, *arguments)
    end
  elsif method_id.match(/^dpmt_.*\?$/)
     ()
end

  下面解釋一下我的思路:

  • 約定查找用戶的權限的方法名為can_do?。假設想確認Jack有沒有游泳的權限,則如下那麼寫:
1
Jack.can_swim?
  • Jack發現他本身並沒有can_swim?方法,在一系列的處理後他最終調用用了method_missing方法。
  • method_missing簡單來說只做一件事,判斷Jack是否有swim的權限。
  • 如果想看看Jack有沒有跑步的權限,則直接使用can_run方法,重複以上三個步驟即可。

  對比java,如果需要判斷swin、run、jump三個動作,我們怎麼做?

  • 寫三個can_xx方法。(代碼重複,擴展性差)
  • 寫一個can(xx)方法,每次都把動作當作參數傳進去。(純主觀看法,括號很難看,不美觀)
     

  ruby的can_do?是不是很簡單易懂?特別方法尾部畫龍點睛的”?“,比java的is_xx()簡直好看百倍!