莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          1、異常的相等性,如果兩個異常的class、message和backtrace一樣,那么認為這兩個異常是相等的,可以通過==判斷。
          def method
              
          raise 'foobar'
          end

          errors 
          = []
          2.times do
              Thread.new do
                begin
                  method
                rescue 
          => e
                  errors 
          << e
                end
              end.join
          end
          puts errors[
          -2== errors[-1]    #=> true (1.9)   false(1.8)

          2、SystemStackError現在繼承Exception類,而非原來的StandardError:
          1.8 
           
          SystemStackError < StandardError  # => true
          1.9
            
          SystemStackError < StandardError # => nil
             SystemStackError < Exception      #=> true

          3、移除了Exception#to_str方法
          begin
             
          raise "foo"
          rescue
             $!.to_str
          end

          #=> undefind method "to_str" for #<RuntimeError:foo>


          posted @ 2008-10-03 13:26 dennis 閱讀(555) | 評論 (0)編輯 收藏

          1、Proc加了新方法Proc#yield,這只是Proc#call的別名方法,是為了能讓Proc也可以像block那樣傳入方法并且調用yield。
          a_proc = Proc.new {|a,b| a+b}
          a_proc.
          yield(1,2# => 3

          def test(&block)
            block.
          yield(1,2,3)
          end
          test do 
          |a,b|
             a
          +b   # => 3
          end
          test 
          &a_proc # =>3

          2、沒有參數的block的基數(參數個數,arity):
          1.8
            
          lambda{}.arity  #=> -1
          1.9
            
          lambda{}.arity #=> 0
          所謂arity就是方法調用無法忽略的參數個數。這跟Erlang,Prolog中的arity的概念并無二致。

          3、proc關鍵字現在是Proc.new的同義詞,proc在1.8的時候跟lambda關鍵字是同義詞,也就是proc定義的是一個lambda而非字面

          意義上的Proc,1.9改過來了。
          1.9:

          proc{
          |a,b|}.arity        # => 2
          proc{|a,b|}.call(1)        # => nil
          Proc.new{|a,b|}.arity        # => 2
          Proc.new{|a,b|}.call(1)        # = nil

          1.8:
          proc{|a,b|}.arity        # => 2
          proc{|a,b|}.call(1)        # => ERROR: (eval):1: wrong number of arguments (1 for 2)
          Proc.new{|a,b|}.arity        # => 2
          Proc.new{|a,b|}.call(1)        # => nil

          1.8時候第二個調用出錯的原因在于lambda在調用參數過多過少的時候都將報error,這是lambda跟Proc的一個區別之一。

          4、Proc#lambda? 用來判斷某個Proc是否具有lambda語義或者block語義:
          lambda{}.lambda?  #=>true
          proc{}.lambda# =>false
          Proc.new{}.lambda# =>false



          posted @ 2008-10-02 13:54 dennis 閱讀(691) | 評論 (0)編輯 收藏

          三、類和模塊
          1、Module#instance_methods, #private_instance_methods, #public_instance_methods Module這三個方法都將返回方法名

          的symbol組成的數組,而非過去的字符串數組。

          2、Module#const_defined?, #const_get 這兩個方法都添加一個參數flag,用來決定是否將它的ancestor中的const包括在查
          找鏈中,例如:
          module A; X = 1def foo; end end
          module B
            include A
            const_defined? 
          "X"                              # => true
            const_defined? "X",false                        #uninitialized constant
            const_get "X"                                   # => 1
            const_get "X",false                             #uninitialized constant  
          end

          3、Module#class_variable_defined?方法:
          class X; end
          X.class_variable_defined? :@@a                    
          # => false
          class X; @@a = 1 end
          X.class_variable_defined? :@@a                     
          # => true
          class_variable_{get,set}方法:

          class B; self end.class_variable_set(:@@a, "foo")        # => "foo"

          4、Module#attr等價于Module#attr_reader:
          class Test
            attr:foo
            
          def initialize
              @foo
          =3
            end
          end
          t
          =Test.new
          puts t.foo   
          #=>3
          t.foo=4     #undefined method "foo="

          5、接下來是一個bug fix的問題。下面這段代碼是為了證明對象的singleton類繼承自對象的類:
          class X;end; x=X.new; class << x;p self < X; end

          在1.8上,這段代碼打印nil,這是不符合Ruby的對象模型的,因此在1.9運行已經可以打印正確結果true了。
          如果不理解這點,參照俺過去寫的《Ruby對象模型》

          6、新增Module#module_exec方法,與Object#instance_exec類似

          7、綁定未綁定的方法時進行額外的子類型檢查,例如下面的代碼:
          class Foo; def foo; end end
          module Bar
             define_method(:foo, Foo.instance_method(:foo))
          end
          a
          =""
          a.extend Bar
          a.foo

          在1.8上,這段代碼只有當執行到a.foo的時候才報錯:"foo":bind arguments must be an instance of Foo(TypeError)
          因為foo是Foo的instance method,因此調用者必須是Foo或者其子類的instance。 而在1.9中,在綁定還沒有綁定的方法的時候引入了額
          外的檢查,因此上面這段代碼不必等到a.foo調用就將報錯:
          class Foo; def foo; end end
          module Bar
             define_method(:foo, Foo.instance_method(:foo))   
          #=》 in "defined_method":bind arguments  must be a subclass

          of Foo
          <TypeError>
          end

          8、binding#eval方法,新增加的:
          a=1
          binding.eval(
          "p a")  => 1

          這個貌似與1.8中的:
          a=1
          eval(
          "a",binding)

          沒有什么不同。

          posted @ 2008-10-01 13:52 dennis 閱讀(652) | 評論 (0)編輯 收藏

          二、Kernel 和 Object
          1、引入了BasicObject對象,作為一個頂級的空白狀態對象:
          BasicObject.instance_methods # => [:==,:equal?,:"!",:"!=",:__send__]
          Object.ancestors       # => [Object, Kernel, BasicObject]

          引入這個對象對于Ruby對象體系帶來的影響我還不清楚。
          2、instance_exec方法,允許傳遞參數、self到一個block并執行之,也就是說為特定的instance執行block。
          def magic(obj)
             
          def obj.foo(&block)
               instance_exec(self, a, b, 
          &block)
             end
          end
          = Struct.new(:a,:b).new(1,2)
          magic(o)
          puts o.foo{
          |myself,x,y| puts myself.inspect;x + y }

          更多例子:
          = Struct.new(:val).new(1)
          o.instance_exec(
          1){|arg| val + arg }  =>2


          在Ruby 1.8中實現這個方法:
          class Object
            module InstanceExecHelper; end
            include InstanceExecHelper
            
          def instance_exec(*args, &block) # !> method redefined; discarding old instance_exec
              mname = "__instance_exec_#{Thread.current.object_id.abs}_#{object_id.abs}"
              InstanceExecHelper.module_eval{ define_method(mname, 
          &block) }
              begin
                ret 
          = send(mname, *args)
              ensure
                InstanceExecHelper.module_eval{ undef_method(mname) } rescue nil
              end
              ret
            end
          end

          3、Kernel的require方法載入的文件將以完整路徑存儲在變量$"中,等價于:
          $" << File.expand_path(loaded_file)

          通過在irb中觀察$"變量即可看出差別。

          4、Object#tap方法,將對象傳入block并返回自身,用于鏈式調用:
          "hello".tap{|a| a.reverse!}[0] #=> "o"
          "F".tap{|x| x.upcase!}[0]  #=> "F" (注意到"F".upcase!返回的是nil)

          5、Kernel#instance_variable_defined?方法:
          = "foo"
          a.instance_variable_defined? :@a                  
          # => false
          a.instance_variable_set(:@a, 1)
          a.instance_variable_defined? :@a                  
          # => true

          6、Object#=~

          匹配失敗的時候返回nil而不是false
          1 =~ 1 # => nil

          7、Kernel#define_singleton_method 方法,
          = ""
          a.define_singleton_method(:foo){
          |x| x + 1}
          a.send(:foo,
          2)  =>3
          a.foo(
          2)  => 3

          8、Kernel#singleton_methods, Kernel#methods,返回的是將是方法名symbol組成的數組,過去是方法名的字符串數組。


          posted @ 2008-10-01 13:48 dennis 閱讀(602) | 評論 (0)編輯 收藏


          一、新的語法和語義
          1、新的Hash定義語法:
          例如{a:2}  等價于 {:a=>2}
          但是 {"a":2} 出錯,并不等價于 {:"a"=>2}

          2、試驗性質的block內的局部變量
          在1.8,block的與外部同名的變量是同一個變量,也就是說block內的變量也可以修改外部的同名變量,這很容易形成難以查找的bug。
          例子:
          # {常規參數;局部變量}
          = 2
          = lambda{|;d| d = 1}
          a.call()
          d        
          # => 2

          注意到,分號后的d是block局部變量。

          3、block的參數現在都是局部變量

          4、新lambda語法,試驗性質:
          ->a,b {a+b}.call(1,2)   => 3

          一些比較詭異的寫法:
          -> { }.call # => nil
          -> a, b  { a + b }.call(1,2# => 3
          = 1-> a, b; c  { c = a + b }.call(1,2); c # => 1(注意這里,;號的c是block的局部變量,因此c=1在lambda調用前后沒有改變。)

          5、 .()的調用方式
          過去
          lambda{|*d| d}.call(1,2,3)

          現在可以簡化為
          lambda{|*d| d}.(1,2,3)

          .()這樣的方式都將調用接受者的call方法,無論接收者是什么,例如:
           "foo".(1,2)   # ~>  undefined method `call' for "foo":String (NoMethodError)

          顯然,這個方式另一種形式上的method_missing,比如在類中應用:

          class Test
            
          def self.call(*d)
               d
             end
          end
          Test.(
          1,2,3)  => [1,2,3]
          這個特性也是試驗性質

          6、block可以使用&block做參數咯。
          例子:
          class Test
             define_method :foo 
          lambda{|&b| b.call("hello")}
          end
          t
          =Test.new
          t.foo do 
          |b|
             puts b    
          => hello
          end

          7、新的block參數語義,|v| 現在等價于 |v,|
          還是通過例子吧:
          1.8:
          def m; yield 12; end
          m{
          |v| v}                                          # => [1, 2]
                                                            # !> multiple values for a block parameter (2 for 1)
          1.9:
          def m; yield 12; end
          m{
          |v| v}                                          # => 1

          8、允許數組多重展開
          def foo(*a)
               a
          end
          foo(
          1*[2,3], 4*[5,6])                        # => [1, 2, 3, 4, 5, 6]

          = [1,2,3]
          = [4,5,6]
          [
          *a, *b]                                         # => [1, 2, 3, 4, 5, 6]

          9、可選參數后允許再有強制參數的存在,這在過去是不允許的。例如下面的代碼在1.8是錯誤的,而1.9卻可以正常運行:
          def foo(a,b="test",c)
            puts c
          end
          foo(
          1)   => wrong number of arguments(1 for 2)
          foo(
          1,2=> 2
          foo(
          1,3=> 3
          foo(
          1,2,3)  =>3
          更復雜的:
          def m(a, b=nil, *c, d)
               [a,b,c,d]
          end
          m(
          1)  =>error
          m(
          1,2)  => [1,nil,[],2]
          m(
          1,2,3=>[1,2,[],3]
          m(
          1,2,3,4)  =>[1,2,[3],4]
          m(
          1,2,3,4,5)   => [1,2,[3,4],5]
          m(
          1,2,3,4,5,6]  =>[1,2,[3,4,5],6]

          10、?c的語義,過去?+字符返回字符的ascii碼整數,現在返回字符"c"
          例如:
          ?a  => 97  (1.8)
          ?a  
          => "a" (1.9)

          11、[]方法的參數現在可以將數組和hash聯合使用,例如下面的例子:
          class Test
             
          def [](*a)
               puts a.inspect
             end
          end
          a
          =[1,2,3]
          Test.new[
          *a,:a=>2]   =>  SyntaxERROR:compire error (1.8)
          Test.new[
          *a,:a=>2=>  [1,2,3,{:a=>2}] (1.9)


          12、打印字符,打印字符和負數,
          1.8
            printf 
          "%c","a"  => can't convert String into Integer
            printf "%u",-1   => ..4294967295

          1.9:
            printf 
          "%c","a"  => a
            printf 
          "%u",-1   => -1
          13、defined?方法和local variable:

          RUBY_VERSION                                      
          # => "1.8.5"
          RUBY_RELEASE_DATE                                 # => "2006-08-25"
          = 0
          defined? a                                        
          # => "local-variable"
          1.times do |i|
            defined? i                                      
          # => "local-variable(in-block)"
          end

          VS.

          RUBY_VERSION                                      
          # => "1.9.0"
          RUBY_RELEASE_DATE                                 # => "2007-08-03"
          = 0
          defined? a                                        
          # => "local-variable"
          1.times do |i|
            defined? i                                      
          # => "local-variable"
          end

          posted @ 2008-10-01 13:37 dennis 閱讀(772) | 評論 (0)編輯 收藏

              與鋒爺、小朱、阿寶中午打的直奔會場,上了酒店五層,發T-shirt,要求換上。立馬在衛生間上演一處猛男秀。來的人不少,我們都坐到后排去鳥,一開始在放某個關于opensource的video,鳥語聽力很差再加上隔的遠字幕都看不清,只好到處看看等待開始。2點半正式開始,先是Peter cheng做個open source camp的介紹,然后是品高的架構師分享了他們電信增殖業務一個項目的架構——用ActiveMQ構建的異步消息隊列。Peter cheng再次現身介紹了objectweb(有無拼錯)社區,什么四方國件中法聯合,不是很清楚,有點昏昏欲睡(當天凌晨3點睡的覺,毋怪)。
             接下來是此次活動的正題,大伙提交想要分享的topic,然后分成幾個時間點和房間開講。由活動參與者來提供topic這樣的形式挺新奇,遺憾的是大多數人并沒有準備,最后還是僅有9個topic(有無記錯?),3個關于python的,一個老外講敏捷(?),一位香港的開發者的經驗分享(聽不懂廣東話),兩個關于集群的topic,還有個MM(后來知道是廣發銀行的)關于開源與商業的topic,一個javascript的科普topic(貌似是關于jquery)。遺憾的是沒有關于Ruby的topic。topic不多,就不用啥投票了,休息片刻,灌了兩瓶礦泉水,大伙如鳥獸散到各個會議室,正題開始。
              我跟阿寶先去聽了CPUG社區的大媽關于金山內部python訓練營的培訓經驗的topic,該訓練營叫蟒營,傳說中的大媽穿了件“人生苦短,我用python”的哲思T-shirt,其實我一直想設計個T-shirt,上面印上一行字“Ruby恒久遠,一顆永流傳”。這個蟒營采用的是魔鬼高壓訓練法,將學生仔訓練成職業開發者,加上大媽煽動,聽著還是蠻有意思。俺比較疑惑的類似這樣的高壓訓練法盡管能快速地挑選出合適的人,但是完全讓學生去自學、放任自流的方法似乎也會浪費不少有潛質的學生,畢竟再好的苗子也需要鋤草。大媽演講另一個關鍵字就是靠譜,專業是很容易裝出來的,一堆大詞加上一表人才是很容易zhuangbility,而能實際干活出東西是才是kaopubility。時間不多,互動比較少,匆匆聽完,趕去聽Peter cheng的關于高可用性集群的topic。內容沒多少新意,主要介紹的是在負載均衡、企業應用集群、數據庫集群上開源領域相對于商業的替代解決方案:LVS、Terracotta、上面提到的objectweb社區的uns/controller(有無記錯?)。一直在強調的一點是解決方案的透明性,如何不侵入地透明地解決企業應用的集群問題。
              聽完這個后,大概5點多了,阿寶趕著去參加同學婚宴,俺也昏昏欲睡了,也就跟著阿寶一起撤退了,比較遺憾沒有去聽那個關于python組件的topic。第一次參加此類活動,盡管見到了傳說中的司令等人,但是俺這個從來沒有名片的倒不好意思去認識下,以后有機會再說了。



          posted @ 2008-09-21 08:58 dennis 閱讀(2038) | 評論 (6)編輯 收藏

          看看甘肅日報消息

          本報蘭州9月13日訊(記者牛彥君)記者今天從省質量月活動現場了解到,我省質監系統在全省全面展開了乳制品專項監督檢查,并對與三鹿集團有合作關系的酒泉市好牛乳業食品有限公司的產品全部封存,乳粉生產線已于9月10日查封,工作組也已于9月12日到達該企業。

          “三鹿奶粉事件”發生后,省質監局立即啟動應急預案積極應對,迅速組成了應急工作領導小組展開調查。9月9日,從住院患者處、定西市安定區、 岷縣、漳縣和蘭州市永登縣緊急抽取了部分樣品,由甘肅省產品質量監督檢驗中心進行檢驗,現已在由石家莊三鹿股份有限公司生產的“三鹿慧幼”1至3段的5個 批次的該產品中檢出了嚴禁在食品和飼料中添加的有毒物質———三聚氰胺,2段乳粉最高值達2563毫克/100克。同時,鈣、鉀、脂肪、鈣磷比、亞硝酸鹽等指標也不符合標準要求。為了保證檢驗的準確性,同時將4個樣品送國家食品質檢中心進行檢驗,檢驗結果一致。我省質監系統已于9月11日開始對該產品實施查封。

          看看昨天抽查結果:
          檢出三聚氰胺嬰幼兒配方乳粉企業名單序號 標稱的企業和產品名稱 抽樣數 不合格數 三聚氰胺最高含量mg/kg

          1、石家莊三鹿集團股份有限公司生產的三鹿牌嬰幼兒配方乳粉 11 11 2563.00

          兩種單位:mg/100g和mg/kg,盡管都是2563

          哦耶,將造假進行到底。

          posted @ 2008-09-17 09:46 dennis 閱讀(674) | 評論 (1)編輯 收藏

              最近各地出現很多嬰兒膽結石的病例,并且這些患病嬰兒吃的是同一品牌的奶粉,本來還遮遮掩掩說什么某品牌,早有人捅出來說是三鹿啊,還抵賴個啥啊。三鹿現在自己也承認了:
               新華網北京9月11日電(記者周婷玉)石家莊三鹿集團股份有限公司11日晚發布產品召回聲明,稱經公司自檢發現2008年8月6日前出廠的部分批次三鹿嬰幼兒奶粉受到三聚氰胺的污染,市場上大約有700噸。

            為對消費者負責,三鹿集團公司決定立即對2008年8月6日以前生產的三鹿嬰幼兒奶粉全部召回。

            衛生部專家指出,三聚氰胺是一種化工原料,可導致人體泌尿系統產生結石。


              問題是真的是被污染的嗎?請google、baidu 三聚氰胺和蛋白兩個關鍵詞。看看結果如何!原來三聚氰胺是奸商們用來提高產品蛋白含量以蒙混過關的化工原料。說要支持國貨,如此作為的著名國貨讓人怎么支持。




          posted @ 2008-09-11 23:55 dennis 閱讀(1981) | 評論 (6)編輯 收藏


          主要是比較offer跟poll兩個方法的性能,開N個線程,每個線程往隊列里寫或者取500個整數。

          線程數
          20
          50
          100
          200
          500 1000
          LinkedBlockingQueue     
          15,0
          31,15
          32,16
          63,32
          203,47
          563,110
          ArrayBlockingQueue 15,0
          16,15
          31,15
          47,16
          125,47
          364,68
          PriorityBlockingQueue 78,78
          172,188
          360,422
          813,969
          3094,2641
          6547,5453

          逗號前的數字是offer測試花費的時間,逗號后的數字是poll測試花費的時間,單位毫秒。
          結論:
          1、ArrayBlockingQueue性能優于LinkedBlockingQueue,但是LinkedBlockingQueue是無界的。
          2、ArrayBlockingQueue和LinkedBlockingQueue的poll方法總是比offer方法快,并發越高,差距越大
          3、ArrayBlockingQueue和LinkedBlockingQueue的性能遠高于PriorityBlockingQueue,顯然優先隊列在比較優先級上的操作上耗費太多
          4、PriorityBlockingQueue的offer方法與poll方法的性能差距很小,基本維持在近似1:1

          posted @ 2008-09-08 10:05 dennis 閱讀(5850) | 評論 (5)編輯 收藏

              任何應用都需要與資源打交道,這個資源可能是文件、內存、網絡、數據庫、web服務等。特別是系統的可伸縮性和性能上,一個系統的可伸縮性很大程度上取決于該系統資源管理的可伸縮性。資源的獲取是資源生命周期的起點,因此在此階段的優化和配置對系統性能、可用性、穩定性、可伸縮性的影響是至關重要的。資源的獲取要解決 這么兩個問題:怎么找到資源,何時獲取資源。
              資源的超找可以通過lookup模式,所謂lookup模式就是引入一個查找服務作為中介,讓資源使用者可以 找到并使用資源提供者提供的資源。這方面一個顯然的例子就是JNDI,我們通過JNDI查找EJB、數據庫連接池等,另一個例子就是RMI,客戶端通過命名服務查找到遠程對象。查找服務提供查詢語言,也提供接口讓服務注冊到它的容器內。
              何時獲取資源?根據時機的不同可以分為預先獲取模式和延遲獲取模式。如果對系統的可用性和運行時性能要求比較高,那么可能你會預先加載或者分配所要用到的資源,通過一個資源提供者的代理對象攔截對資源的請求,返回預先加載或者分配的資源,從而提高系統性能。這方面的例子就是 memcached,memcached啟動時預先分配內存來提高性能(相應的帶來的是內存的不能有效利用)。線程池、數據庫連接池也是預先獲取模式的例子,通過預先創建的線程或者數據庫連接,來提高系統的整體性能。反之,延遲獲取模式就是盡可能到使用資源的最后一刻才去獲取資源,一開始返回的只是一個資源的代理對象,真正使用到資源的時候由這個代理對象去加載實際的資源。延遲獲取模式的例子也很多,例如 Hibernate的延遲加載,延遲加載的對象其實是一個代理類(通過java動態代理或者cglib增強),只有真正用到的時候才去數據庫獲取實際的數 據。函數式編程中的延時求值也是延遲獲取模式的例子,沒有求值前只是個promise,求值到的時候才force執行。Singleton模式下的單例也常常做延遲初始化,這是延遲獲取模式的特化。
              如果資源的大小很大、極大或者是未知尺寸,預先獲取會導致系統速度的緩慢甚至耗盡系統資源,延遲獲取在獲取的時候也可能時間過長難以忍受或者耗盡系統資源,兩者都不適合,解決辦法就是分步獲取,這就是所謂部分獲取模式。將資源的獲取分為兩步或者多步,每一步獲取一定數目的資源,每一步獲取資源也可以采用預先或者延遲的策略。這樣的例子如socket讀數據到緩沖區,一次可能只讀一部分數據到緩沖區,分步才讀完。再比如web頁面一棵樹的展 現,一開始可能只是顯示部分節點,在需要查看一些節點的時候才會通過ajax加載和展開它們的子結點乃至深層子結點。

          參考:POSA3 第二章

          posted @ 2008-09-07 22:10 dennis 閱讀(2481) | 評論 (1)編輯 收藏

          僅列出標題
          共56頁: First 上一頁 22 23 24 25 26 27 28 29 30 下一頁 Last 
          主站蜘蛛池模板: 清苑县| 云南省| 新河县| 汕尾市| 腾冲县| 南昌市| 厦门市| 乌拉特前旗| 合江县| 朝阳市| 门头沟区| 滨海县| 贵德县| 襄垣县| 尉氏县| 滕州市| 彭山县| 西林县| 曲松县| 三都| 攀枝花市| 丰原市| 渝中区| 瓮安县| 浙江省| 合作市| 惠东县| 大庆市| 略阳县| 桐乡市| 怀安县| 资兴市| 盘锦市| 沙坪坝区| 桐庐县| 万宁市| 桃园县| 涞源县| 连云港市| 邹平县| 长武县|