Dynamically create a method

Is there a possiblilty to dynamically create a method, like this?

Fixnum.create_method(:power) do |a|
self ** a
end

or - perhaps easier:

Fixnum.create_method(‘power’) do |me, a|
me ** a
end

I tried to implement such a create_method, but all I came up with was
a solution using a global array of method objects:

def Object.add_method(name, m)
$methods ||= []
$methods << m
module_eval "def #{name}(*args); $methods[#{$methods.length() - 1}].call(self, *args); end"
end

Fixnum.add_method ‘square_plus’, proc { |me, x|
me * me + x
}

I certainly don’t like this hack.

It would be great to have this if one wants to implement something
along the lines of Perl’s autoloader. In the missing_method method,
one would read in the method one wants to add (or dynamically create it)
and add it to the class.

Oh… an autoloader can be done differently, by having the "method files"
look like

MyClass.meth0.al:
class MyClass
def meth0()
# …
end
end

MyClass.foo.al:
class MyClass
def foo()
# …
end
end

But I’d still like to know how to dynamically create a method with a
dynamically given name. If possible, without such a hackery.

Is that possible?

···


[mpg123d] Just playing: …/ayumi hamasaki/a best/01 a song for xx.mp3

Das Erzeugen von C-Code ist sehr fehlerhaft und klappt nur bei ganz
einfachen Programmen. [Alvar Freude in de.comp.lang.perl.misc]

Hi,

···

At Sat, 15 Mar 2003 03:02:08 +0900, Rudolf Polzer wrote:

Is there a possiblilty to dynamically create a method, like this?

Fixnum.create_method(:power) do |a|
self ** a
end

Module#define_method, in 1.8.


Nobu Nakada

Rudolf Polzer wrote:

But I’d still like to know how to dynamically create a method with a
dynamically given name. If possible, without such a hackery.

irb(main):003:0> Fixnum.instance_eval {define_method(:power) do |a| self
** a end}
#Proc:0x40210220@:3(irb)
irb(main):004:0> 3.power 2
9

The instance_eval is because it’s a private method.

Scripsit ille »Joel VanderWerf« vjoel@PATH.Berkeley.EDU:

Rudolf Polzer wrote:

But I’d still like to know how to dynamically create a method with a
dynamically given name. If possible, without such a hackery.

irb(main):003:0> Fixnum.instance_eval {define_method(:power) do |a| self
** a end}
#Proc:0x40210220@:3(irb)
irb(main):004:0> 3.power 2
9

The instance_eval is because it’s a private method.

Thanks… but where is it documented? I know rb_define_method (so I
should have just tried without the rb_)…

···


[mpg123d] Just playing: …/MP3/ayumi hamasaki/a best/07 trauma.mp3

Doch - alles, was dazu mich trieb,
Gott! war so gut! ach, war so lieb!

Rudolf Polzer wrote:

But I’d still like to know how to dynamically create a method with a
dynamically given name. If possible, without such a hackery.

irb(main):003:0> Fixnum.instance_eval {define_method(:power) do |a| self
** a end}
#Proc:0x40210220@:3(irb)
irb(main):004:0> 3.power 2
9

The following doesn’t work with 1.6.8, has it been fixed in 1.8?

class Foo < String; end
Foo.instance_eval { define_method(:gsub,*a) { puts “hello”; super } }
Foo.new(“test”).gsub(/t/,‘z’)

x.rb:2: super called outside of method

Regards,

Brian.

···

On Sat, Mar 15, 2003 at 05:35:09AM +0900, Joel VanderWerf wrote:

isn’t this easier?

class Fixnum
def power(exp)
self ** exp
end
end

a=10
a.power 2

robert

“Joel VanderWerf” vjoel@PATH.Berkeley.EDU schrieb im Newsbeitrag
news:3E723D76.9090807@path.berkeley.edu…

Rudolf Polzer wrote:

But I’d still like to know how to dynamically create a method with
a
dynamically given name. If possible, without such a hackery.

irb(main):003:0> Fixnum.instance_eval {define_method(:power) do |a|
self

···

** a end}
#Proc:0x40210220@:3(irb)
irb(main):004:0> 3.power 2
9

The instance_eval is because it’s a private method.

Scripsit ille »Rudolf Polzer« abuse@durchnull.de:

Scripsit ille »Joel VanderWerf« vjoel@PATH.Berkeley.EDU:

Rudolf Polzer wrote:

But I’d still like to know how to dynamically create a method with a
dynamically given name. If possible, without such a hackery.

irb(main):003:0> Fixnum.instance_eval {define_method(:power) do |a| self
** a end}
#Proc:0x40210220@:3(irb)
irb(main):004:0> 3.power 2
9

The instance_eval is because it’s a private method.

Thanks… but where is it documented? I know rb_define_method (so I
should have just tried without the rb_)…

And… it doesn’t work here because “self” refers to the class Fixnum, not to
the Fixnum object:

rpolzer@katsuragi rpolzer $ irb
irb(main):001:0> Fixnum.instance_eval {define_method(:power) do |a| self ** a end}
=> #Proc:0x4006bf00
irb(main):002:0> 3.power 2
NameError: undefined method **' for Fixnum:Class from (irb):1 from (irb):1:in power’
from (irb):2

I have Ruby 1.6.8.

Do I need another way to access the “self”?

···


[mpg123d] Just playing: …/MP3/ayumi hamasaki/a best/07 trauma.mp3

PLONCK
[Pitt Marin in de.comm.technik.dsl]

Scripsit ille »Robert Klemme« bob.news@gmx.net:

isn’t this easier?

class Fixnum
def power(exp)
self ** exp
end
end

a=10
a.power 2

It is, but there might be cases where one does not know the name of the
method in advance. Perhaps when dynamically creating more than one method
in method_missing().

And… wasn’t there a way to convert a string to a symbol?

···


In diesem Sinne kannst du’s wagen.
Verbinde dich! du sollst in diesen Tagen
Mit Freuden meine Künste sehn;
Ich gebe dir, was noch kein Mensch gesehn.

rpolzer@katsuragi rpolzer $ irb
irb(main):001:0> Fixnum.instance_eval {define_method(:power) do |a| self ** a end}
=> #Proc:0x4006bf00
irb(main):002:0> 3.power 2
NameError: undefined method **' for Fixnum:Class from (irb):1 from (irb):1:in power’
from (irb):2

I have Ruby 1.6.8.

Do I need another way to access the “self”?

It is a difference of 1.6 and 1.7 or later, according to ja/man-1.6
http://www.ruby-lang.org/ja/man-1.6/?cmd=view;name=Module

In 1.6, the block parameter of Module.define_method is evaluated in
defining-time context (in this case, the self is Fixnum class object
rather than 3, the receiver object).
In 1.7 and later, the block is eval’ed with the receiver object
using instance_eval.

					FUKUMOTO Atsushi
					fukumoto@imasy.or.jp

“Rudolf Polzer” abuse@durchnull.de schrieb im Newsbeitrag
news:slrnb7b7ev.as5.abuse@durchnull.de

Scripsit ille »Robert Klemme« bob.news@gmx.net:

isn’t this easier?

class Fixnum
def power(exp)
self ** exp
end
end

a=10
a.power 2

It is, but there might be cases where one does not know the name of the
method in advance.

This wasn’t obvious from the original poster’s example. But I agree, for
those cases one of the eval approaches has to be used.

Perhaps when dynamically creating more than one method
in method_missing().

Hm, I could not imagine a scenario where method_missing is used to
actually create methods. Typically I’d create them before they are
missed. Can you provide an example?

And… wasn’t there a way to convert a string to a symbol?

Yes:

irb(main):006:0> “foo”.intern.type
Symbol
irb(main):007:0>

Ciao

robert

Hm, I could not imagine a scenario where method_missing is used to
actually create methods. Typically I'd create them before they are
missed. Can you provide an example?

plruby (procedural language for PostgreSQL) can load methods stored in the
database (because it run with $SAFE >= 4 require is not possible). Because
it can't predict which methods will be used by the user it use
method_missing to define these methods.

Guy Decoux

Scripsit ille »Robert Klemme« bob.news@gmx.net:

“Rudolf Polzer” abuse@durchnull.de schrieb im Newsbeitrag news:slrnb7b7ev.as5.abuse@durchnull.de

Scripsit ille »Robert Klemme« bob.news@gmx.net:

isn’t this easier?

class Fixnum
def power(exp)
self ** exp
end
end

a=10
a.power 2

It is, but there might be cases where one does not know the name of the
method in advance.

This wasn’t obvious from the original poster’s example. But I agree, for
those cases one of the eval approaches has to be used.

Perhaps when dynamically creating more than one method
in method_missing().

Hm, I could not imagine a scenario where method_missing is used to
actually create methods. Typically I’d create them before they are
missed. Can you provide an example?

With only ONE method, it’s easy. For example Perl’s autoloader does
exactly that.

Example in Ruby:

autoload.rb:
class Autoloaded
def method_missing(method, *args)
p “Autoloading #{method.to_s()}…”
require(“Autoloaded/#{method.to_s()}.rb”)
send(method, *args)
end
def bar()
p “In non-autoloaded method”
end
end

x = Autoloaded.new()
x.bar()
x.foo()
x.foo()
x.bar()
x.baz()

Autoloaded/foo.rb:
class Autoloaded
def foo()
p “In autoloaded method.”
end
end

Example:

rpolzer@katsuragi ruby $ ruby autoload.rb
“In non-autoloaded method”
“Autoloading foo…”
“In autoloaded method.”
“In autoloaded method.”
“In non-autoloaded method”
“Autoloading baz…”
autoload.rb:4:in require': No such file to load -- Autoloaded/baz.rb (LoadError) from autoload.rb:4:in method_missing’
from autoload.rb:17

Please do NOT use this simple autoloader. If you want to know why,
try creating an empty file “Autoloaded/baz.rb” and see what happens.
It’s oversimple. Alternatively, do a typo in the class or method
name of Autoloaded/foo.rb - you’ll get the same bad result.

But I did not find an example for dynamically creating a method with
dynamically created name… but you can dynamically undefine a method,
so you should also be able to define one. And it NEARLY works…
except that self seems to be inaccessible. My method completely works,
but self has to be accessed with another name and it uses a global array
→ ugly.

And… wasn’t there a way to convert a string to a symbol?

Yes:

irb(main):006:0> “foo”.intern.type

“intern” was it… thanks.

Why not “to_symbol” or like that?

···


Nimm dich in acht vor ihren schönen Haaren,
Vor ihrem Schmuck, mit dem sie einzig prangt.
Wenn sie damit den jungen Mann erlangt,
So läßt sie ihn so bald nicht wieder fahren.

“ts” decoux@moulon.inra.fr schrieb im Newsbeitrag
news:200303171253.h2HCrdc24815@moulon.inra.fr

Hm, I could not imagine a scenario where method_missing is used to
actually create methods. Typically I’d create them before they are
missed. Can you provide an example?

plruby (procedural language for PostgreSQL) can load methods stored in
the
database (because it run with $SAFE >= 4 require is not possible).
Because
it can’t predict which methods will be used by the user it use
method_missing to define these methods.

Ah! Thanks for that!

robert

“Rudolf Polzer” abuse@durchnull.de schrieb im Newsbeitrag
news:slrnb7bi5g.4qv.abuse@durchnull.de

Scripsit ille »Robert Klemme« bob.news@gmx.net:

Hm, I could not imagine a scenario where method_missing is used to
actually create methods. Typically I’d create them before they are
missed. Can you provide an example?

With only ONE method, it’s easy. For example Perl’s autoloader does
exactly that.

Ok, I see. Thanks!

And… wasn’t there a way to convert a string to a symbol?

Yes:

irb(main):006:0> “foo”.intern.type

“intern” was it… thanks.

Why not “to_symbol” or like that?

IMHO better, since intern() reminds me of java.lang.String.intern() which
returns a String and not a symbol.

Regards

robert