Yet Another Rite Thought: method combination

Ask a Question related to Ruby, Design and Development.

  1. #1

    Default Yet Another Rite Thought: method combination

    I just looked at matz' slides and I don't have a clear understanding
    of ho9w this is suposed to work.

    Possibly this has been explained verbosely, But I can't get it from
    the slide.

    So, this is the example:

    class Foo
    def foo(*args) #1
    p 'foo'
    end
    def foo:pre (*args ) #2
    p 'pre'
    end
    def foo:post (*args) #3
    p 'post'
    end
    def foo:wrap (*args) #4
    p 'wrap pre'
    super
    p 'wrap post'
    end
    end

    now: what are pre post and wrap?

    Are this just generic (casual) names for the wrapping functions? (so
    we could have def foo:bar)

    Are they wrapping idioms ?
    if true
    what do they are for? Do the work as in :
    pre called before the method
    post called after the method
    wrap could call super and get the old method
    I suppose pre and post are actually useless this way, cause they
    can be emulated with foo:wrap()
    or do the work as
    pre wraps the original method
    post wraps the latest wrapping of the method
    wrap ... ?


    someone would please explain this to me ?
    gabriele renzi Guest

  2. Similar Questions and Discussions

    1. [Rite] Byte-Code Compiler in Ruby
      Hi, I am fascinated by the many new ideas presented by matz for Rite. Why not write the whole Ruby-to-Bytecode compiler in Ruby itself? As...
    2. Exif data: Is APE only program left to get this rite?
      Please see below the note I posted in another newsgroup about a program that may end up being my FORMER favorite, Paint Shop Pro. I just looked in...
    3. Rite/Ruby2.0 & Ruby vs OCaml
      Hi All, I'm new here, and I hope I don't offend anyone by mentioning a different programming language here on Ruby-Talk. I have two questions...
    4. Ruby => Rite, AST => Bytecode?
      Matz and fellow Rubyists, On pragprog, we're sort-of discussing the creation of a new language ("Pragmatic") as an exercise in extending one's...
    5. matz thoughts on Rite ?
      I don't know much about Rite, therefore I ask. I would like to fill in some more info on this page: http://www.rubygarden.org/ruby?Rite ...
  3. #2

    Default Re: Yet Another Rite Thought: method combination

    On Monday, November 17, 2003, 6:22:18 PM, gabriele wrote:
    > I just looked at matz' slides and I don't have a clear understanding
    > of ho9w this is suposed to work.
    > Possibly this has been explained verbosely, But I can't get it from
    > the slide.
    > So, this is the example:
    > class Foo
    > def foo(*args) #1
    > p 'foo'
    > end
    > def foo:pre (*args ) #2
    > p 'pre'
    > end
    > def foo:post (*args) #3
    > p 'post'
    > end
    > def foo:wrap (*args) #4
    > p 'wrap pre'
    > super
    > p 'wrap post'
    > end
    > end
    > now: what are pre post and wrap?
    > [...]
    > someone would please explain this to me ?

    The slide demonstrates it adequately. Given the above code:

    Foo.new.foo
    # Output:
    # wrap pre
    # pre
    # foo
    # post
    # wrap post

    Gavin


    Gavin Sinclair Guest

  4. #3

    Default Re: Yet Another Rite Thought: method combination

    --------------000000030805040502010902
    Content-Type: text/plain; charset=us-ascii; format=flowed
    Content-Transfer-Encoding: 7bit

    Gavin Sinclair wrote:
    >On Monday, November 17, 2003, 6:22:18 PM, gabriele wrote:
    >
    >
    > someone would please explain this to me ?
    >
    >
    >
    >The slide demonstrates it adequately. Given the above code:
    >
    > Foo.new.foo
    > # Output:
    > # wrap pre
    > # pre
    > # foo
    > # post
    > # wrap post
    >
    >
    This is a feature from CLOS that allows you to add hooks to arbitrary
    methods. The names 'pre', 'post' and 'wrap' are predefined and can't be
    changed. This isn't a generic way to sort of chain methods together;
    it's sort of AOP-lite. For any method 'foo' you can define any
    combination of foo:pre, foo:post and foo:wrap. According to Matz, you
    can't change the parameters in a pre, can't change the return value in a
    post, but you CAN do both in a wrap. The output snippet above shows the
    order of calls if you define all three.

    Joey


    --------------000000030805040502010902--


    Joey Gibson Guest

  5. #4

    Default Re: Yet Another Rite Thought: method combination


    "Gavin Sinclair" <gsinclair@soyabean.com.au> schrieb im Newsbeitrag
    news:1174425281.20031117234546@soyabean.com.au...
    > On Monday, November 17, 2003, 6:22:18 PM, gabriele wrote:
    >
    > > I just looked at matz' slides and I don't have a clear understanding
    > > of ho9w this is suposed to work.
    >
    > > Possibly this has been explained verbosely, But I can't get it from
    > > the slide.
    >
    > > So, this is the example:
    >
    > > class Foo
    > > def foo(*args) #1
    > > p 'foo'
    > > end
    > > def foo:pre (*args ) #2
    > > p 'pre'
    > > end
    > > def foo:post (*args) #3
    > > p 'post'
    > > end
    > > def foo:wrap (*args) #4
    > > p 'wrap pre'
    > > super
    > > p 'wrap post'
    > > end
    > > end
    I find the "super" a bit strange here. It looks like it was implied that
    for all methods "foo" there is an implicit "foo:wrap" defined by the Ruby
    runtime in a super class of the actual class. I'd prefer another keyword,
    such as "previous", "original" or so since the semantics differ. Or did I
    get the meaning of "super" in this context wrong?

    Regards

    robert

    Robert Klemme Guest

  6. #5

    Default Re: Yet Another Rite Thought: method combination

    >>>>> "R" == Robert Klemme <bob.news@gmx.net> writes:

    R> I find the "super" a bit strange here. It looks like it was implied that
    R> for all methods "foo" there is an implicit "foo:wrap" defined by the Ruby
    R> runtime in a super class of the actual class.

    well, I've not understood

    super is in Foo#foo:wrap : this mean that if ruby call foo:wrap
    then it exist at least the method Foo#foo which will be called latter

    super, in this case, just assume that it exist another wrapper or the
    original method.

    R> I'd prefer another keyword,
    R> such as "previous", "original" or so since the semantics differ.

    call-next-method :-)))

    R> Or did I
    R> get the meaning of "super" in this context wrong?

    probably,


    Guy Decoux





    ts Guest

  7. #6

    Default Re: Yet Another Rite Thought: method combination


    "ts" <decoux@moulon.inra.fr> schrieb im Newsbeitrag
    news:200311171638.hAHGcvO07164@moulon.inra.fr...
    > >>>>> "R" == Robert Klemme <bob.news@gmx.net> writes:
    >
    > R> I find the "super" a bit strange here. It looks like it was implied
    that
    > R> for all methods "foo" there is an implicit "foo:wrap" defined by the
    Ruby
    > R> runtime in a super class of the actual class.
    >
    > well, I've not understood
    >
    > super is in Foo#foo:wrap : this mean that if ruby call foo:wrap
    > then it exist at least the method Foo#foo which will be called latter
    >
    > super, in this case, just assume that it exist another wrapper or the
    > original method.
    Yeah, but "super" generally refers to the same method defined in another
    class up the inheritance hierarchy. That's a chain different from the
    wrapping chain.
    > R> I'd prefer another
    keyword,
    > R> such as "previous", "original" or so since the semantics differ.
    >
    > call-next-method :-)))
    or the even more typing friendly "invoke-next-wrapper-or-original-method"
    :-)))

    (Sorry, I couldn't find something more longish.)
    > R> Or
    did I
    > R> get the meaning of "super" in this context wrong?
    >
    > probably,
    Not from what you wrote: "super" invokes whatever is next in the wrapping
    chain at whose end the original method resides. Thanks anyway.

    Cheers

    robert

    Robert Klemme Guest

  8. #7

    Default Re: Yet Another Rite Thought: method combination

    >>>>> "R" == Robert Klemme <bob.news@gmx.net> writes:

    R> Not from what you wrote: "super" invokes whatever is next in the wrapping
    R> chain at whose end the original method resides.

    Can you explain me why you see a problem with `super' but don't see a
    problem with `def' ?


    Guy Decoux




    ts Guest

  9. #8

    Default Re: Yet Another Rite Thought: method combination

    il Mon, 17 Nov 2003 22:23:27 +0900, Gavin Sinclair
    <gsinclair@soyabean.com.au> ha scritto::
    >On Monday, November 17, 2003, 6:22:18 PM, gabriele wrote:
    >
    >> I just looked at matz' slides and I don't have a clear understanding
    >> of ho9w this is suposed to work.
    >
    >The slide demonstrates it adequately. Given the above code:
    >
    > Foo.new.foo
    > # Output:
    > # wrap pre
    > # pre
    > # foo
    > # post
    > # wrap post
    >
    I'm dumb I can admit thois :)
    But, This could work both with idea #2 or #3.
    The point is: if #2 is right (pre is called before the method. post is
    called after the real method. wrap can call super.) what is the need
    for pre and post? thay can be easily done transparently with wrap?

    Does foo:post add itself to the first foo() definition or to the
    latest redefinition?

    what is the 'method resolution order' for method wrapping?

    wrap->post->pre?

    pre->post->wrap?

    latest-definition-wins ?

    if I did:

    class Foo
    def foo:wrap (*args) #4
    p 'wrap pre'
    super
    p 'wrap post'
    end
    def foo(*args) #1
    p 'foo'
    end
    def foo:pre (*args ) #2
    p 'pre'
    end
    def foo:post (*args) #3
    p 'post'
    end
    end

    Foo.new.foo would give the same output or would it give

    pre
    wrap pre
    foo
    wrap post
    post

    ?

    sorry for being stupid :(
    gabriele renzi Guest

  10. #9

    Default Re: Yet Another Rite Thought: method combination

    gabriele renzi wrote:
    > The point is: if #2 is right (pre is called before the method. post is
    > called after the real method. wrap can call super.) what is the need
    > for pre and post? they can be easily done transparently with wrap?
    Based on what I heard Matz say during the presentation, you are correct
    that the 'pre' and 'post' methods' behavior can be emulated with the
    'wrap' method, i.e. this:

    class Foo
    def foo; p "foo"; end
    def foo:pre; p "pre"; end
    def foo:post; p "post"; end
    end

    and this:

    class Foo
    def foo
    p "foo"
    end
    def foo:wrap
    p "pre"
    result = super
    p "post"
    result
    end
    end

    would produce equivalent results.
    > Does foo:post add itself to the first foo() definition or to the
    > latest redefinition?
    This was not specified (I think).
    > what is the 'method resolution order' for method wrapping?
    >
    > wrap->post->pre?
    >
    > pre->post->wrap?
    >
    > latest-definition-wins?
    Not sure I understand. "wrap" (if it exists) is the entry point, so it
    has the first shot. Inside foo:wrap, if you call super (i.e. invoke the
    wrapped method), it will call foo:pre (if it exists), then foo, then
    foo:post (if it exists).
    > if I did:
    >
    > class Foo
    > def foo:wrap (*args) #4
    > p 'wrap pre'
    > super
    > p 'wrap post'
    > end
    > def foo(*args) #1
    > p 'foo'
    > end
    > def foo:pre (*args ) #2
    > p 'pre'
    > end
    > def foo:post (*args) #3
    > p 'post'
    > end
    > end
    >
    > Foo.new.foo would give the same output or would it give
    >
    > pre
    > wrap pre
    > foo
    > wrap post
    > post
    >
    > ?
    For this example, Foo.new.foo would print:

    wrap pre
    pre
    foo
    post
    wrap post
    > sorry for being stupid :(
    Not stupid. And hopefully I haven't given you bad information here ;)

    Lyle

    Lyle Johnson Guest

  11. #10

    Default Re: Yet Another Rite Thought: method combination

    On Mon, 17 Nov 2003 07:22:01 +0000, gabriele renzi wrote:
    > I just looked at matz' slides and I don't have a clear understanding
    > of ho9w this is suposed to work.
    >
    > Possibly this has been explained verbosely, But I can't get it from
    > the slide.
    >
    > So, this is the example:
    >
    > class Foo
    > def foo(*args) #1
    > p 'foo'
    > end
    > def foo:pre (*args ) #2
    > p 'pre'
    > end
    > end
    How about something like ?

    This is only a partial example.. I have no clue how to do it with proc's.
    But there should be a convertion from yield-block to proc.

    server> ruby a.rb
    before #test
    42
    after #test
    server> expand -t2 a.rb
    class Object
    def self.def_pre(*args)
    args.each{|symbol|
    begin
    meth = instance_method(symbol)
    rescue => e
    $stderr.puts "ERROR: symbol2method failure, " + e.inspect
    next
    end
    name = symbol.id2name
    org = "_defpre_"+name
    arguments = (meth.arity != 0) ? "(*a,&b)" : "(&b)"
    module_eval <<MSG
    alias #{org} #{name}
    def #{name}#{arguments}
    $stdout.puts("before ##{name}")
    #{org}#{arguments}
    $stdout.puts("after ##{name}")
    ensure
    $debug = nil
    end
    private :#{org}
    MSG
    }
    end
    end

    class A
    def test; p 42 end
    end

    class B < A
    def_pre :test #{ puts "pre" }
    end

    B.new.test
    server>


    --
    Simon Strandgaard
    Simon Strandgaard Guest

  12. #11

    Default Re: Yet Another Rite Thought: method combination

    il Mon, 17 Nov 2003 23:47:31 +0100, Simon Strandgaard
    <qj5nd7l02@sneakemail.com> ha scritto::

    >How about something like ?
    there was already a working implementation of method wrapping.. google
    for
    'how I'd like method $x to work'
    $x is something like 'wrapping' 'hook' 'decoration'

    Just this is ruby code and not interprter level..
    gabriele renzi Guest

  13. #12

    Default Re: Yet Another Rite Thought: method combination

    gabriele renzi wrote:
    > il Mon, 17 Nov 2003 23:47:31 +0100, Simon Strandgaard
    > <qj5nd7l02@sneakemail.com> ha scritto::
    >
    >
    >
    >>How about something like ?
    >
    >
    > there was already a working implementation of method wrapping.. google
    > for
    > 'how I'd like method $x to work'
    > $x is something like 'wrapping' 'hook' 'decoration'
    >
    > Just this is ruby code and not interprter level..
    >
    I started that thread: [url]http://ruby-talk.org/71948[/url]

    Here are my comments on Matz's plan:

    1. First of all, I will be happy with whatever Matz
    decides. I will never flame the one who gave us Ruby.

    2. I'm a little bothered by the use of 'super' also.
    I once suggested 'prior'; but I can (now) see that
    using super does not introduce ambiguity.

    3. It strikes me that wrap is really the only one
    necessary. It could do all the work of pre and post.
    Yet I suppose the others are good from the standpoint
    of clarity.

    4. I'm a little bothered that 'post' is not able to
    know the return value of the method even though the
    method has returned. (In theory we could use a call
    to super that simply accessed the return value rather
    than making a real call.) This is a motivation for
    me to use wrap more often than post.

    Just my thoughts.

    Hal



    Hal Fulton Guest

  14. #13

    Default Re: Yet Another Rite Thought: method combination


    "Hal Fulton" wrote:
    >
    > Here are my comments on Matz's plan:
    >
    > [...]
    >
    > 3. It strikes me that wrap is really the only one
    > necessary. It could do all the work of pre and post.
    > Yet I suppose the others are good from the standpoint
    > of clarity.
    >
    A similar argument might be made for attr_accessor
    - making attr_reader & attr_writer unnecessary.

    OK, there's a ton of reasons why "that's not the same
    thing" (the best reason I can think of is that "they're
    not the same thing";).

    Whereas attr_* contains overlapping functionality,
    hooking doesn't appear to suffer in the same way.

    Wrap is a controlling 'outer' wrap. The combination of
    pre/post would be a benign 'inner' wrap. Benign in the
    sense that you could safely assume that you wouldn't
    accidentally be changing the program's logic.

    Here (#+#) is the statement I add when I'm about to wreck logic:

    class Roo
    def r
    7 * 6
    #+# print 'r done ... '
    end
    end
    p Roo.new.r # -> 42
    #+# p Roo.new.r # -> r done ... nil

    If I understand :post, I should be able to add the method by:

    class Roo
    def r:post
    print 'r done ... '
    end
    end
    p Roo.new.r # -> r done ... 42

    > 4. I'm a little bothered that 'post' is not able to
    > know the return value of the method even though the
    > method has returned.
    But if :wrap is also defined, its back-end is about to get
    control. If you want to know the return value, the only
    sensible place to find out is in :wrap because you might
    leave it as it is, or change it, and it can't(?) be
    changed any later.
    >
    > Just my thoughts.
    >
    > Hal
    >

    I'm just adding by trivial example that :pre or :post will
    be better to use when :wrap might be over-kill.

    Acknowledgements to Guy and/or CLOS language.


    daz



    daz Guest

  15. #14

    Default Re: Yet Another Rite Thought: method combination

    daz wrote:
    > Wrap is a controlling 'outer' wrap. The combination of
    > pre/post would be a benign 'inner' wrap. Benign in the
    > sense that you could safely assume that you wouldn't
    > accidentally be changing the program's logic.
    actually, i think, with a programming language like ruby, worrying about changing program logic is sort of like worrying about strong typing. i think most rubyists are more instrested in having the control, even if measn we can break things. its not like we can't fix them! :) in light of this i've been thinking about allowing complete access to methods and lambdas through an array like interface, where each statment is indexed. something like:

    pm = lambda { p 'hi'; x = 4; x }
    pm[0] # => { p 'hi' }
    pm[1] # => { x = 4 }
    pm[2] # => { x }

    so each statment is like a little lambda. then you can actually manipulate these:

    pm << { x + 1 }
    pm[0..-1] # => { p 'hi'; x = 4; x; x + 1 }
    pm[0] = lambda { p 'hello' } if pm[0].to_s.include?('hi')

    which is like a wrap, but much more "aware".

    of course this requires a little panning out of the syntax to work well. but ruby is so dynamic, i imagine it is quite possible.

    -t0

    p.s. you'll find this idea explained a little more, and generalized to all structures, in my RCR.

    T. Onoma Guest

  16. #15

    Default Re: Yet Another Rite Thought: method combination


    "ts" <decoux@moulon.inra.fr> schrieb im Newsbeitrag
    news:200311171717.hAHHH9408208@moulon.inra.fr...
    > >>>>> "R" == Robert Klemme <bob.news@gmx.net> writes:
    >
    > R> Not from what you wrote: "super" invokes whatever is next in the
    wrapping
    > R> chain at whose end the original method resides.
    >
    > Can you explain me why you see a problem with `super' but don't see a
    > problem with `def' ?
    Well, def foo:wrap still defines a method, but if you insist, we can
    change that, too. :-))

    Cheers

    robert

    Robert Klemme Guest

  17. #16

    Default Re: Yet Another Rite Thought: method combination

    >>>>> "R" == Robert Klemme <bob.news@gmx.net> writes:

    R> Well, def foo:wrap still defines a method,

    Are you sure ?

    Now how do you see that super don't follow the inheritence hierarchy ?

    In the example, matz use only one class, difficult to speak about
    inheritence with only one class


    Guy Decoux



    ts Guest

  18. #17

    Default Re: Yet Another Rite Thought: method combination

    ts wrote:

    ...
    > R> Well, def foo:wrap still defines a method,
    >
    > Are you sure ?
    >
    > Now how do you see that super don't follow the inheritence
    > hierarchy ?
    >
    > In the example, matz use only one class, difficult to speak
    > about inheritence with only one class
    So the meaning of super varies when used in the wrap context.
    What will be the meaning of super when used in foo:pre or
    foo:post? While I kind of like the hook scheme I am not sure
    I if like this C++/Java-ish keyword overloading.


    /Christoph


    Christoph Guest

  19. #18

    Default Re: Yet Another Rite Thought: method combination


    "ts" <decoux@moulon.inra.fr> schrieb im Newsbeitrag
    news:200311180929.hAI9TUu19761@moulon.inra.fr...
    > >>>>> "R" == Robert Klemme <bob.news@gmx.net> writes:
    >
    > R> Well, def foo:wrap still defines a method,
    >
    > Are you sure ?
    Well, it is not exactly a method like others, but it defines
    functionality.
    > Now how do you see that super don't follow the inheritence hierarchy ?
    >
    > In the example, matz use only one class, difficult to speak about
    > inheritence with only one class
    :-))

    Exactly. That's why I think "super" is inappropriate here.

    robert

    Robert Klemme Guest

  20. #19

    Default Re: Yet Another Rite Thought: method combination

    >>>>> "R" == Robert Klemme <bob.news@gmx.net> writes:

    R> Exactly. That's why I think "super" is inappropriate here.

    Can you give me an example with 2 classes (inheritance + wrappers) ?


    Guy Decoux





    ts Guest

  21. #20

    Default Re: Yet Another Rite Thought: method combination

    ts wrote:
    ...
    > Can you give me an example with 2 classes (inheritance + wrappers) ?
    class A
    def foo
    p "A"
    end
    def foo:pre
    p "pre_a"
    end
    def foo:post
    p "post_a"
    end

    def foo:wrap
    super
    p "A"
    end
    end

    class B < A
    def foo
    super
    p "B"
    end
    def foo:pre
    super
    p "pre_b"
    end
    def foo:post
    super
    p "post_b"
    end

    def foo:wrap
    super
    p "B"
    end
    end


    /Christoph


    Christoph Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139