Greetings again! I'm trying to create a user-defined class on the fly.
The idea would be for the user to provide a class name, maybe a
superclass name, and some method definition as a string, e.g.
str1 = "MyClass"
str2 = "Class"
str3 = "def bar \n p \"bar!\" \n end"
and then my program would perhaps do something like
eval "class #{str1} < #{str2}\n #{str3} \n end"
So far so good. Security is not a concern, this is just for a proof of
concept. But I would like to be able to then extend MyClass
separately, e.g.
module Mod
def bar
p "foo!"
end
end
class ???
include Mod
end
I'm stuck on the ??? part. I tried
class eval( str1 )
I tried
class str.intern # (I think I know by now why this one was a stupid idea)
I tried
$myclassref = eval str1
class $myclassref
All to no avail. So I'm wondering whether I'm trying to do this the
wrong way. What would be the Ruby way of solving this problem?
To give you a better idea of what I was looking for, I'm trying to do
the Ruby equivalent of this Smalltalk code
>myClassname myCat myClass|
myCat := 'Foo Classes'.
myClassname := 'MyClass'.
(Smalltalk hasClassNamed: myClassname) ifTrue: [Smalltalk
removeClassNamed: myClassname].
(Smalltalk organization) addCategory:myCat before: 'Kernel-Methods'.
(ClassBuilder new) superclass:Object subclass: (myClassname
asSymbol) instanceVariableNames:''
classVariableNames: '' poolDictionaries: '' category: myCat.
myClass := Smalltalk classNamed: myClassname.
myClass addInstVarName: 'x';addClassVarName: 'X'.
(myClass respondsTo: ('getx' asSymbol)) ifFalse:[
myClass compile: 'getx
^ x' classified: 'accessors'].
(myClass canUnderstand: ('getX' asSymbol)) ifFalse:[
myClass compile: 'getX
^ X' classified: 'accessors'].
Transcript clear;show: (myClass definition).
Transcript cr;show: (myClass selectors).
(myClass new) perform: ('getx' asSymbol); perform: ('getX' asSymbol).
Cheers!
-CWS
···
On Sat, 14 Aug 2004 15:30:57 -0400, Claus Spitzer <docboobenstein@gmail.com> wrote:
Greetings again! I'm trying to create a user-defined class on the fly.
The idea would be for the user to provide a class name, maybe a
superclass name, and some method definition as a string, e.g.
str1 = "MyClass"
str2 = "Class"
str3 = "def bar \n p \"bar!\" \n end"
and then my program would perhaps do something like
eval "class #{str1} < #{str2}\n #{str3} \n end"
So far so good. Security is not a concern, this is just for a proof of
concept. But I would like to be able to then extend MyClass
separately, e.g.
module Mod
def bar
p "foo!"
end
end
class ???
include Mod
end
I'm stuck on the ??? part. I tried
class eval( str1 )
I tried
class str.intern # (I think I know by now why this one was a stupid idea)
I tried
$myclassref = eval str1
class $myclassref
All to no avail. So I'm wondering whether I'm trying to do this the
wrong way. What would be the Ruby way of solving this problem?
Greetings again! I'm trying to create a user-defined class on the fly.
The idea would be for the user to provide a class name, maybe a
superclass name, and some method definition as a string, e.g.
[...]
So far so good. Security is not a concern, this is just for a proof of
concept. But I would like to be able to then extend MyClass
separately, e.g.
module Mod
def bar
p "foo!"
end
end
class ???
include Mod
end
I'm stuck on the ??? part. I tried
def make_class(name, p, code); r = Class.new(p.split(/::/).inject(Object){|s,x|s.const_get(x)}); Object.const_set(name, r); r.module_eval code; r end
=> nil
class A; class B; end end
=> nil
klass = make_class "Foo", "A::B", "def bar; 'bar' end"
=> Foo
klass.ancestors
=> [Foo, A::B, Object, Kernel]
klass.new.bar
=> "bar"
You can later modify klass dynamically with module_eval, define_method,
etc.
···
On Sun, Aug 15, 2004 at 04:31:11AM +0900, Claus Spitzer wrote:
--
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
Great! Thanks for the quick response. Just another quick one on that context:
Now that I have the class definition and can extend it easily, I'm
wondering how I would do
qux = Klass.new
using str1 or klass. I could do
eval "qux = #{str}.new"
and that would be fine, but it somehow seems forced. Any hints?
···
On Sun, 15 Aug 2004 04:40:41 +0900, Sam Stephenson <sstephenson@gmail.com> wrote:
On Sun, 15 Aug 2004 04:31:11 +0900, Claus Spitzer > <docboobenstein@gmail.com> wrote:
> I'm stuck on the ??? part. I tried
>
> class eval( str1 )
>
> I tried
>
> class str.intern # (I think I know by now why this one was a stupid idea)
>
> I tried
>
> $myclassref = eval str1
> class $myclassref
>
> All to no avail. So I'm wondering whether I'm trying to do this the
> wrong way. What would be the Ruby way of solving this problem?
>
> klass = eval(str1)
> klass.class_eval do
> include Mod
> end
Sam
Claus Spitzer wrote:
Great! Thanks for the quick response. Just another quick one on that context:
Now that I have the class definition and can extend it easily, I'm
wondering how I would do
qux = Klass.new
using str1 or klass. I could do
eval "qux = #{str}.new"
and that would be fine, but it somehow seems forced. Any hints?
Hmm. If I understand the question, the following should work:
klass = eval( str )
qux = klass.new
- Jamis
···
--
Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck.org/jamis
"I use octal until I get to 8, and then I switch to decimal."
Err... actually I just figured that out myself a minute ago :-p . I'm
not at my brightest today. Thanks for the reply though!
···
Hmm. If I understand the question, the following should work:
klass = eval( str )
qux = klass.new
- Jamis
--
Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck.org/jamis
"I use octal until I get to 8, and then I switch to decimal."