Determine method passed and determine the receiver that received the method

“Robert Klemme” bob.news@gmx.net schrieb im Newsbeitrag news:…

“Peña, Botp” botp@delmonte-phil.com schrieb im Newsbeitrag

news:1030AB5FAD0A3847B7B1F7B93332AFB501E18290@bgmail00.delmonte-phil.com

Hi Friends,

Forgive me in adv for asking a newbie question.

  1. First question: How do I get the the method passed?

Eg.

cat test1.rb
#-------------------------
class Dog
def bark
‘arf!arf!’
end
def method_missing(x)
p “method missing”
“sorry, cannot do #{x} in #{self}”
end
end

beethoven = Dog.new
p beethoven.bark
p beethoven.purr
#-------------------------

ruby -w test1.rb
“arf!arf!”
“sorry, cannot do purr in #Dog:0x2777228

I’d like a method similar to method_missing(x) (wherein the methodname
is
passed in x), but only access it before a method is run (maybe name it
method_called(x)).

So I can do (maybe),


Class Dog

def method_called(x)
p “You ask for #{x}”
end
end

Tracing is one option. See
http://www.rubycentral.com/book/ref_m_kernel.html#Kernel.set_trace_func

Another option is to use a similar scheme as in Delegator and
automatically
generate proxy methods that invoke your “method_called” just before they
hand over control to the real method.
http://www.rubycentral.com/book/lib_patterns.html

Which of the approaches you choose depends on your situation.

Tehre might be another option to define a module / class method that
automatically creates a new method that first invokes method_called and
the
the original method. Sorryy, I don’t have the time at the moment to put
such a thing together.

Cancel that. This works:

class Module
def notify(sym)
new_sym = “#{sym}_old”.intern
alias_method new_sym.to_s, sym.to_s

define_method sym do |*args|
  puts "#{sym} called with args: #{args.inspect}"
  send( new_sym, *args )
end

end
end

class Foo
def bar
puts “bar!”
end

notify :bar
end

Foo.new.bar

Regards

robert

Cancel that. This works:

class Module
def notify(sym)
new_sym = “#{sym}_old”.intern
alias_method new_sym.to_s, sym.to_s

define_method sym do |*args|

Isn’t it a shame that you cannot propagate blocks with define_method?

Maybe we could use Kernel.block_given, with the obvious semantics.

  puts "#{sym} called with args: #{args.inspect}"
  send( new_sym, *args )
end

end
end

class Foo
def bar
yield
puts “bar!”
end

notify :bar
end

Foo.new.bar { puts “Bomb” }

batsman@tux-chan:/tmp$ ruby f.rb
f.rb:24: warning: block for Proc#bar is useless
bar called with args:
f.rb:17:in bar_old': no block given (LocalJumpError) from f.rb:9:in send’
from f.rb:9:in bar' from f.rb:7:in bar’
from f.rb:24

···

On Sun, Jan 25, 2004 at 05:04:58AM +0900, Robert Klemme wrote:


_ _

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

  • SynrG notes that the number of configuration questions to answer in sendmail
    is NON-TRIVIAL
    – Seen on #Debian

“Mauricio Fernández” batsman.geo@yahoo.com schrieb im Newsbeitrag
news:20040124235621.GA7427@student.ei.uni-stuttgart.de

···

On Sun, Jan 25, 2004 at 05:04:58AM +0900, Robert Klemme wrote:

Cancel that. This works:

class Module
def notify(sym)
new_sym = “#{sym}_old”.intern
alias_method new_sym.to_s, sym.to_s

define_method sym do |*args|

Isn’t it a shame that you cannot propagate blocks with define_method?

Yeah, that’s true. I ran into it while figuring how to do it.

Regards

robert

What would you think about Kernel::block_given, returning a Proc
corresponding to the block or nil?

In the current situation you have to choose between having a closure
and propagating the block :stuck_out_tongue:

···

On Sun, Jan 25, 2004 at 10:14:56PM +0900, Robert Klemme wrote:

“Mauricio Fernández” batsman.geo@yahoo.com schrieb im Newsbeitrag
news:20040124235621.GA7427@student.ei.uni-stuttgart.de

On Sun, Jan 25, 2004 at 05:04:58AM +0900, Robert Klemme wrote:

Cancel that. This works:

class Module
def notify(sym)
new_sym = “#{sym}_old”.intern
alias_method new_sym.to_s, sym.to_s

define_method sym do |*args|

Isn’t it a shame that you cannot propagate blocks with define_method?

Yeah, that’s true. I ran into it while figuring how to do it.


_ _

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

  • liw prefers not to have Linus run Debian, because then /me would
    have to run Red Hat, just to keep the power balance :slight_smile:
    #Debian

“Mauricio Fernández” batsman.geo@yahoo.com schrieb im Newsbeitrag
news:20040125140229.GA13890@student.ei.uni-stuttgart.de

“Mauricio Fernández” batsman.geo@yahoo.com schrieb im Newsbeitrag
news:20040124235621.GA7427@student.ei.uni-stuttgart.de

Cancel that. This works:

class Module
def notify(sym)
new_sym = “#{sym}_old”.intern
alias_method new_sym.to_s, sym.to_s

define_method sym do |*args|

Isn’t it a shame that you cannot propagate blocks with
define_method?

Yeah, that’s true. I ran into it while figuring how to do it.

What would you think about Kernel::block_given, returning a Proc
corresponding to the block or nil?

I don’t like it because it imposes the additional overhead of a proc
creation even for cases when you just want the boolean information. How
about extending Proc to accept blocks like this:

proc {|foo, &bl|
puts “foo=#{foo}”
bl.call if bl
}

Or at least extend Proc#call to use blocks. Currently this is what
happens:

irb(main):063:0> proc {|*args| p args; p block_given? ; yield }
…call(1,2,3) { puts “block!” }
[1, 2, 3]
false
LocalJumpError: no block given
from (irb):63
from (irb):63:in `call’
from (irb):63

Matz, this is not too big a change, is it?

Regards

robert
···

On Sun, Jan 25, 2004 at 10:14:56PM +0900, Robert Klemme wrote:

On Sun, Jan 25, 2004 at 05:04:58AM +0900, Robert Klemme wrote:
from :0

Hi

···

In message “Blocks as Block / Proc parameters” on 04/01/26, “Robert Klemme” bob.news@gmx.net writes:

How |about extending Proc to accept blocks like this:

proc {|foo, &bl|
puts “foo=#{foo}”
bl.call if bl
}

Matz, this is not too big a change, is it?

Too big for the current implementation. But I plan to accept your
idea in the future Ruby2.

						matz.

We have Kernel.block_given? already… so having Kernel.block_given too
seems most natural to me, and it looks easier to implement than adding
an optional &block to the block args.

···

On Mon, Jan 26, 2004 at 07:55:00PM +0900, Robert Klemme wrote:

What would you think about Kernel::block_given, returning a Proc
corresponding to the block or nil?

I don’t like it because it imposes the additional overhead of a proc
creation even for cases when you just want the boolean information. How
about extending Proc to accept blocks like this:


_ _

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

Not only Guinness - Linux is good for you, too.
– Banzai on IRC

“Yukihiro Matsumoto” matz@ruby-lang.org schrieb im Newsbeitrag
news:1075120740.175475.1867.nullmailer@picachu.netlab.jp…

Hi

How |about extending Proc to accept blocks like this:

proc {|foo, &bl|
puts “foo=#{foo}”
bl.call if bl
}

Matz, this is not too big a change, is it?

Too big for the current implementation. But I plan to accept your
idea in the future Ruby2.

Hey, that’s cool! :slight_smile:

robert
···

In message “Blocks as Block / Proc parameters” > on 04/01/26, “Robert Klemme” bob.news@gmx.net writes:

“Mauricio Fernández” batsman.geo@yahoo.com schrieb im Newsbeitrag
news:20040126132501.GA14179@student.ei.uni-stuttgart.de

What would you think about Kernel::block_given, returning a Proc
corresponding to the block or nil?

I don’t like it because it imposes the additional overhead of a proc
creation even for cases when you just want the boolean information.
How
about extending Proc to accept blocks like this:

We have Kernel.block_given? already… so having Kernel.block_given too
seems most natural to me, and it looks easier to implement than adding
an optional &block to the block args.

Oha, I guess it is as susceptible for typos as my eyes reading your
posting: I read “block_given?” which I embarrassed have to admit was not
what you wrote. Sorry for that.

Still I’d prefer the other approach (using “&b” to get the block or
allowing to “yield”) because it is more consistent with the current
software and has not this just-one-character-difference gotcha.

Regards

robert
···

On Mon, Jan 26, 2004 at 07:55:00PM +0900, Robert Klemme wrote: