[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Setting Class Methods Using Strings

Demonic Software

3/13/2008 5:29:00 AM

[Note: parts of this message were removed to make it a legal post.]

Hello,

First question:
With the 'print 'foo_method called with \#{arg}', is there a way to escape
the "#" so that arg will not be evaluated until after the statement is
evalled? For example:

Let c be "'print 'foo_method called with \#{arg}'"

eval(c) => print 'foo_method called with #{arg}'



Second (Main Question)
Is it possible to set an object's methods with raw code and a method name?
I am not sure how to Google for an example on this, so I will just show an
example.

== Here is an empty class definition Foo, and later on I will want to
assign/add/set a method in an instantiated Foo object ==

class Foo
end

== Now I want to set a method in an instantiated Foo with code, so that I
can call f ==

code = "def foo_method(arg)
print 'foo_method called with #{arg}'
end"

f = Foo.new()
#...
#code to set a method in f
#...

f.foo_method("for the win!")

==

Is this possible? or Do I need create a string and add the method in like
the following example?

code = "\ndef foo_method(arg)
print 'foo_method called with \#{arg}'
end\n"
foo = "class Foo " + code + " end"

eval(foo)
f = Foo.new()
f.foo_method("for the win!")



Thanks in advance for your help.

3 Answers

Chris Shea

3/13/2008 5:49:00 AM

0

On Mar 12, 11:29 pm, Demonic Software <demonic.softw...@gmail.com>
wrote:
> [Note: parts of this message were removed to make it a legal post.]
>
> Hello,
>
> First question:
> With the 'print 'foo_method called with \#{arg}', is there a way to escape
> the "#" so that arg will not be evaluated until after the statement is
> evalled? For example:
>
> Let c be "'print 'foo_method called with \#{arg}'"
>
> eval(c) => print 'foo_method called with #{arg}'
>
> Second (Main Question)
> Is it possible to set an object's methods with raw code and a method name?
> I am not sure how to Google for an example on this, so I will just show an
> example.
>
> == Here is an empty class definition Foo, and later on I will want to
> assign/add/set a method in an instantiated Foo object ==
>
> class Foo
> end
>
> == Now I want to set a method in an instantiated Foo with code, so that I
> can call f ==
>
> code = "def foo_method(arg)
> print 'foo_method called with #{arg}'
> end"
>
> f = Foo.new()
> #...
> #code to set a method in f
> #...
>
> f.foo_method("for the win!")
>
> ==
>
> Is this possible? or Do I need create a string and add the method in like
> the following example?
>
> code = "\ndef foo_method(arg)
> print 'foo_method called with \#{arg}'
> end\n"
> foo = "class Foo " + code + " end"
>
> eval(foo)
> f = Foo.new()
> f.foo_method("for the win!")
>
> Thanks in advance for your help.

If you know when to use single quotes and when to use double quotes,
yes to both:


a = 1
c = 'puts "a = #{a}"' # => "puts \"a = \#{a}\""
eval(c) # >> a = 1

code = 'def foo_method(arg); puts "foo_method called with #{arg}";
end'
class Foo; end
Foo.class_eval(code)
Foo.new.foo_method('hi') # >> foo_method called with hi


Single-quoted strings do not perform interpolation, while double-
quoted strings do. So if you juggle them for eval, you can have it do
what you want. Of course, putting a backslash before the #{} in double-
quoted strings will escape that so it doesn't perform the
interpolation.

Play around and you should get the hang of it quickly. And beware
eval. Use carefully.

HTH,
Chris

Demonic Software

3/13/2008 6:07:00 AM

0

[Note: parts of this message were removed to make it a legal post.]

Cool thanks Chris.

On Thu, Mar 13, 2008 at 12:50 AM, Chris Shea <cmshea@gmail.com> wrote:

> On Mar 12, 11:29 pm, Demonic Software <demonic.softw...@gmail.com>
> wrote:
> > [Note: parts of this message were removed to make it a legal post.]
> >
> > Hello,
> >
> > First question:
> > With the 'print 'foo_method called with \#{arg}', is there a way to
> escape
> > the "#" so that arg will not be evaluated until after the statement is
> > evalled? For example:
> >
> > Let c be "'print 'foo_method called with \#{arg}'"
> >
> > eval(c) => print 'foo_method called with #{arg}'
> >
> > Second (Main Question)
> > Is it possible to set an object's methods with raw code and a method
> name?
> > I am not sure how to Google for an example on this, so I will just show
> an
> > example.
> >
> > == Here is an empty class definition Foo, and later on I will want to
> > assign/add/set a method in an instantiated Foo object ==
> >
> > class Foo
> > end
> >
> > == Now I want to set a method in an instantiated Foo with code, so that
> I
> > can call f ==
> >
> > code = "def foo_method(arg)
> > print 'foo_method called with #{arg}'
> > end"
> >
> > f = Foo.new()
> > #...
> > #code to set a method in f
> > #...
> >
> > f.foo_method("for the win!")
> >
> > ==
> >
> > Is this possible? or Do I need create a string and add the method in
> like
> > the following example?
> >
> > code = "\ndef foo_method(arg)
> > print 'foo_method called with \#{arg}'
> > end\n"
> > foo = "class Foo " + code + " end"
> >
> > eval(foo)
> > f = Foo.new()
> > f.foo_method("for the win!")
> >
> > Thanks in advance for your help.
>
> If you know when to use single quotes and when to use double quotes,
> yes to both:
>
>
> a = 1
> c = 'puts "a = #{a}"' # => "puts \"a = \#{a}\""
> eval(c) # >> a = 1
>
> code = 'def foo_method(arg); puts "foo_method called with #{arg}";
> end'
> class Foo; end
> Foo.class_eval(code)
> Foo.new.foo_method('hi') # >> foo_method called with hi
>
>
> Single-quoted strings do not perform interpolation, while double-
> quoted strings do. So if you juggle them for eval, you can have it do
> what you want. Of course, putting a backslash before the #{} in double-
> quoted strings will escape that so it doesn't perform the
> interpolation.
>
> Play around and you should get the hang of it quickly. And beware
> eval. Use carefully.
>
> HTH,
> Chris
>
>

Todd Benson

3/13/2008 7:14:00 AM

0

On Thu, Mar 13, 2008 at 12:29 AM, Demonic Software
<demonic.software@gmail.com> wrote:
> Hello,
>
> First question:
> With the 'print 'foo_method called with \#{arg}', is there a way to escape
> the "#" so that arg will not be evaluated until after the statement is
> evalled? For example:
>
> Let c be "'print 'foo_method called with \#{arg}'"
>
> eval(c) => print 'foo_method called with #{arg}'
>
>
>
> Second (Main Question)
> Is it possible to set an object's methods with raw code and a method name?
> I am not sure how to Google for an example on this, so I will just show an
> example.
>
> == Here is an empty class definition Foo, and later on I will want to
> assign/add/set a method in an instantiated Foo object ==
>
> class Foo
> end
>
> == Now I want to set a method in an instantiated Foo with code, so that I
> can call f ==
>
> code = "def foo_method(arg)
> print 'foo_method called with #{arg}'
> end"
>
> f = Foo.new()
> #...
> #code to set a method in f
> #...
>
> f.foo_method("for the win!")
>
> ==
>
> Is this possible? or Do I need create a string and add the method in like
> the following example?
>
> code = "\ndef foo_method(arg)
> print 'foo_method called with \#{arg}'
> end\n"
> foo = "class Foo " + code + " end"
>
> eval(foo)
> f = Foo.new()
> f.foo_method("for the win!")
>
>
>
> Thanks in advance for your help.

Unless you absolutely _have_ to create a string (like you're holding
code in a database that is to be executed)...

class Foo
end

f = Foo.new
g = Foo.new

def f.bar arg; puts arg; end

f.bar "hi"
# "hi"
g.bar "hi"
# undefined method error

It can also be done like this after the class construction...

class << f
def bar arg; puts arg; end
end

I don't think this case is a good use of #eval, but it depends on what
you're doing.

hth,
Todd