Aliased setter methods behave differently than other methods?

Ask a Question related to Ruby, Design and Development.

  1. #1

    Default Aliased setter methods behave differently than other methods?

    Here's another question... I am aliasing and redefining certain methods,
    determined at runtime. Normal methods work fine, but methods ending in
    '=' are not behaving the same. Here's an example:

    module Mymodule
    def Mymodule.append_features(klass)
    super(klass)
    klass.module_eval do
    def self.enalias(s)
    alias_method(('old_' + s).intern, s.intern)
    module_eval <<-EOF
    def #{s}(arg)
    puts 'hola ' + arg
    old_#{s}(arg)
    end
    EOF
    end
    end
    end
    end

    class Myclass
    def hello(s)
    puts 'hello ' + s
    end
    include Mymodule
    end

    class MyclassQ
    def hello=(s)
    puts 'hello ' + s
    end
    include Mymodule
    end

    c = Myclass.new
    c.hello('1')
    Myclass.enalias('hello')
    c.hello('2')
    c.old_hello('3')
    puts '-----'
    q = MyclassQ.new
    q.hello=('1')
    MyclassQ.enalias('hello=')
    q.hello=('2')
    q.old_hello=('3')

    This outputs the following:

    hello 1
    hola 2
    hello 2
    hello 3
    -----
    hello 1
    hola 2
    hello 3

    Notice that, in the class where the method is "hello=" rather than
    "hello", the call to the old method fails somehow. Its output is skipped.

    Am I missing something obvious here? Are the setters intended to act
    differently somehow? BTW I get this output on both 1.6.8 and 1.8.



    Jim Cain Guest

  2. Similar Questions and Discussions

    1. Help me for RIA Testing methods
      can any one have some good articles on RIA Testing methods or some good Testing plans for RIA?
    2. #40653 [NEW]: strval() and floatval() behave differently
      From: plyrvt at mail dot ru Operating system: Any PHP version: 5.2.1 PHP Bug Type: Strings related Bug description: ...
    3. BeginInvoke Methods
      This is probably going to be obvious to most of you, but I can't seem to figure out the answer. If I have a web service method that I want to call...
    4. Can web methods be overloaded ?
      Can a web method be overloaded? To support varying numbers of input parameters?
    5. #26350 [NEW]: Inherited methods can't access private methods
      From: forseti at oak dot rpg dot pl Operating system: Windows 98 SE PHP version: 5.0.0b2 (beta2) PHP Bug Type: Zend Engine 2...
  3. #2

    Default Re: Aliased setter methods behave differently than other methods?

    Hi,

    At Fri, 18 Jul 2003 14:10:24 +0900,
    Jim Cain wrote:
    > Notice that, in the class where the method is "hello=" rather than
    > "hello", the call to the old method fails somehow. Its output is skipped.
    enalias for hello= will be excuted as bellow:

    alias_method(('old_hello=').intern, 'hello='.intern)
    module_eval <<-EOF
    def hello=(arg)
    puts 'hola ' + arg
    old_hello=(arg) # just local variable assignment.
    end
    EOF

    --
    Nobu Nakada

    nobu.nokada@softhome.net Guest

  4. #3

    Default Re: Aliased setter methods behave differently than other methods?

    [email]nobu.nokada@softhome.net[/email] wrote:
    > Hi,
    >
    > At Fri, 18 Jul 2003 14:10:24 +0900,
    > Jim Cain wrote:
    >
    >>Notice that, in the class where the method is "hello=" rather than
    >>"hello", the call to the old method fails somehow. Its output is skipped.
    >
    >
    > enalias for hello= will be excuted as bellow:
    >
    > alias_method(('old_hello=').intern, 'hello='.intern)
    > module_eval <<-EOF
    > def hello=(arg)
    > puts 'hola ' + arg
    > old_hello=(arg) # just local variable assignment.
    > end
    > EOF
    >
    Of course! Duh. I stared and stared at that one and never saw it from
    Ruby's point of view. Now I just have to figure out how to make it look
    like a method call.


    Jim Cain Guest

  5. #4

    Default Re: Aliased setter methods behave differently than other methods?

    On Fri, Jul 18, 2003 at 11:52:52PM +0900, Brian Candler wrote:
    > > > alias_method(('old_hello=').intern, 'hello='.intern)
    > > > module_eval <<-EOF
    > > > def hello=(arg)
    > > > puts 'hola ' + arg
    > > > old_hello=(arg) # just local variable assignment.
    > > > end
    > > > EOF
    > > >
    > >
    > > Of course! Duh. I stared and stared at that one and never saw it from
    > > Ruby's point of view. Now I just have to figure out how to make it look
    > > like a method call.
    >
    > send("old_#{whatever}", arg)
    That's a lot of work :-)

    self.old_hello=(arg)

    that is,
    self.old_#{s}(arg)

    --
    _ _
    | |__ __ _| |_ ___ _ __ ___ __ _ _ __
    | '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \
    | |_) | (_| | |_\__ \ | | | | | (_| | | | |
    |_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
    Running Debian GNU/Linux Sid (unstable)
    batsman dot geo at yahoo dot com

    <Tazman> damn my office is cold.
    <Tazman> need a hot secretary to warm it up.
    -- Seen on #Linux

    Mauricio Fernández Guest

  6. #5

    Default Re: Aliased setter methods behave differently than other methods?

    On Fri, 18 Jul 2003 23:19:37 +0900, Jim Cain <list@jimcain.us> wrote
    (more or less):
    >nobu.nokada@softhome.net wrote:
    >> Hi,
    >>
    >> At Fri, 18 Jul 2003 14:10:24 +0900,
    >> Jim Cain wrote:
    >>
    >>>Notice that, in the class where the method is "hello=" rather than
    >>>"hello", the call to the old method fails somehow. Its output is skipped.
    >>
    >>
    >> enalias for hello= will be excuted as bellow:
    >>
    >> alias_method(('old_hello=').intern, 'hello='.intern)
    >> module_eval <<-EOF
    >> def hello=(arg)
    >> puts 'hola ' + arg
    >> old_hello=(arg) # just local variable assignment.
    >> end
    >> EOF
    >>
    >
    >Of course! Duh. I stared and stared at that one and never saw it from
    >Ruby's point of view. Now I just have to figure out how to make it look
    >like a method call.

    Errmm, not obvious to me (a newbie). What's the significance of the =
    suffix in amethod name that makes it behave differently

    ?



    Cheers,
    Euan
    Gawnsoft: [url]http://www.gawnsoft.co.sr[/url]
    Symbian/Epoc wiki: [url]http://html.dnsalias.net:1122[/url]
    Smalltalk links (harvested from comp.lang.smalltalk) [url]http://html.dnsalias.net/gawnsoft/smalltalk[/url]
    Gawnsoft Guest

  7. #6

    Default Re: Aliased setter methods behave differently than other methods?

    On Sat, Jul 19, 2003 at 12:04:48AM +0900, Gawnsoft wrote:
    > >Of course! Duh. I stared and stared at that one and never saw it from
    > >Ruby's point of view. Now I just have to figure out how to make it look
    > >like a method call.
    >
    >
    > Errmm, not obvious to me (a newbie). What's the significance of the =
    > suffix in amethod name that makes it behave differently
    foo = x

    is always interpreted as an assignment to local variable 'foo'; and from
    that point onwards in that method, 'foo' by itself is treated as a local
    variable rather than a method. So, a local variable assignment takes
    precedence over any method with the same name which might exist. Hence you
    cannot call a method 'foo=' with the above syntax. You can however specify a
    receiver (self.foo=) or use 'send', in which case it is unambiguously a
    method call.

    Ought to be documented here, but doesn't appear to be :-)
    [url]http://www.rubygarden.org/ruby?ThingsNewcomersShouldKnow[/url]

    Regards,

    Brian.

    Brian Candler Guest

  8. #7

    Default Re: Aliased setter methods behave differently than other methods?

    Okay, this works fine now for setters:

    module_eval <<-EOF
    def #{s}(arg)
    puts 'hola ' + arg
    self.old_#{s}(arg)
    end
    EOF

    But what about the generic case when you don't know how many arguments a
    method takes, and you don't really want to know:

    module_eval <<-EOF
    def #{s}(*arg)
    puts 'hola ' + arg
    self.old_#{s}(*arg) # syntax error
    end
    EOF

    I get a syntax error on the method call, but only for setters. Is a
    method with a name like "somemethod=" required to take exactly one argument?


    Jim Cain Guest

  9. #8

    Default Re: Aliased setter methods behave differently than other methods?

    Jim Cain wrote:
    > Okay, this works fine now for setters:
    >
    > module_eval <<-EOF
    > def #{s}(arg)
    > puts 'hola ' + arg
    > self.old_#{s}(arg)
    > end
    > EOF
    >
    > But what about the generic case when you don't know how many arguments a
    > method takes, and you don't really want to know:
    >
    > module_eval <<-EOF
    > def #{s}(*arg)
    > puts 'hola ' + arg
    > self.old_#{s}(*arg) # syntax error
    > end
    > EOF
    >
    > I get a syntax error on the method call, but only for setters. Is a
    > method with a name like "somemethod=" required to take exactly one
    > argument?
    >
    >
    >
    Oops, sorry, I was too lazy to cut & paste. The last example should've been:

    module_eval <<-EOF
    def #{s}(*arg)
    puts 'hola ' + arg[0]
    self.old_#{s}(*arg) # syntax error
    end
    EOF

    But that of course does not address the syntax error on the old_ method
    call.


    Jim Cain Guest

  10. #9

    Default Re: Aliased setter methods behave differently than other methods?

    On Sat, Jul 19, 2003 at 12:44:14AM +0900, Jim Cain wrote:
    > But what about the generic case when you don't know how many arguments a
    > method takes, and you don't really want to know:
    >
    > module_eval <<-EOF
    > def #{s}(*arg)
    > puts 'hola ' + arg
    > self.old_#{s}(*arg) # syntax error
    > end
    > EOF
    >
    > I get a syntax error on the method call, but only for setters. Is a
    > method with a name like "somemethod=" required to take exactly one argument?
    irb(main):001:0> class Foo
    irb(main):002:1> def x=(a,b)
    irb(main):003:2> puts a,b
    irb(main):004:2> end
    irb(main):005:1> end
    => nil
    irb(main):006:0> a = Foo.new
    => #<Foo:0x81ae97c>
    irb(main):007:0> a.x=(1,2)
    SyntaxError: compile error

    But:

    irb(main):008:0> a.send(:x=,1,2)
    1
    2
    => nil

    Regards,

    Brian.

    Brian Candler Guest

Posting Permissions

  • You may not post new threads
  • You may not 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