凤鸣's profile单身公寓PhotosBlogLists Tools Help

Blog


    June 21

    Another way to implement Delegate pattern

    Earlier we wrote a delegator just like this:
     
    require 'delegate'
    class Hello
        def helloworld()
            "hello world"
        end
    end
    class MyDelegate < SimpleDelegator
        def initialize
            @hello = Hello.new
            super(@hello)
        end
        def setObj
            __setobj__(@hello);
        end
    end
     
    hello =  MyDelegate.new
    hello.setObj
    puts hello.helloworld
     
     
    And now,we can do it as before.But it is difficult to read it,I will give a explanation following.
     
    Let's code...
     
    Come from Jim Weirich's BlankSlate
    class BlankSlate
         instance_methods.each { |m| undef_method m unless m =~ /^__/ }
    end
     
    class Proxy < BlankSlate
      def initialize(obj)
        @obj = obj
      end
      def method_missing(sym, *args, &block)
        puts "Sending #{sym}(#{args.join(',')}) to obj"
        @obj.__send__(sym, *args, &block)
      end
    end
     
    class Hello
        def helloworld() 
            "hello world"
        end
    end
    hello = Hello.new
    n = Proxy.new(hello)
    puts n.helloworld

     
    First,in super class BlankSlate, I iterated all instance method and prevent method calling for child while method name is started by '__'.
    2nd,while a method could not be found in Proxy class,method_missing will invoked.Then your method will be invoked by @obj.__send__(sym, *args, &block) . It's like reflection in Java.
     
     
    May 02

    A Problem about key word "self"

    In Ruby Glossary,I found following content
     
     Technique to call upper level ((<method|Method>))
        from ((<overridden|Override>)) method.
        When argument is omitted, super'ed slave can be called by
        the same argument as that of the master's method.

        : Question:
          If you change the value of ((<variable|Variable>)) given as an argument,
          which 'super' gets, the original value, or the changed?


            def foo(a)
               print a
            end
            def self.foo(a)
               a=25
               super
            end
            foo(5)        # 5 or 25??


        : Answer:
          the original one(((%5%))).


    so I tried this code in SciTE, then the answer is 25.
    In my mind,I think when we use method foo(5), firstly ,self.foo(a) would be invoked.The value of a changed to 25.Then when it traced to super , foo(a) would be invoked.At last ,print a is 25.
    All went well~! Then I wanna try to prove my mind.I used Komodo to debug step by step.But it gave me a surprise,result was 5!! Later, I try again and again,all was not changed.
    So,I think I found a bug of Komodo IDE,but I donot know why.
    April 21

    A implement of delegate pattern in Ruby

    First of all, use SimpleDelegator class
    1.first new a class
    2.new another class extends SimpleDelegator,and donot forget require "delegate" at top of file
    3.in this subclass ,super(obj) should be added in end of method initialize
    4.let's look at code
     
    require 'delegate'
    class Hello
        def helloworld()
            "hello world"
        end
    end
    class MyDelegate < SimpleDelegator
        def initialize
            @hello = Hello.new
            super(@hello)
        end
        def setObj
            __setobj__(@hello);
        end
    end
    hello =  MyDelegate.new
    hello.setObj
    puts hello.helloworld
     
    and then output "hello world" string
     
    Secondly,write a delegator in another way
    1.Code a class extends DelegateClass,and set a parameter that you want to use
    2.Implementing your method initialize ,and donot forget to write super method.
    3.Implementing your method which match to a parameter before you passed
    4.And now,let's code
    require 'delegate'
    

    class MyDelegator < DelegateClass(Array)   def initialize(array)     super(array)   end   def [](*n)     val = super(*n)     #Add your logic here   end end
    and now ,when u add your logic at method [](*n),the class MyDelegator will
    delegate method [] of a Array ,just like this:
    array = %w {22 33 33 44}
    myDelegator = MyDelegator.new(array)
    puts array[0..3]
     
    It will be output the result that u changed in your logic.