From: Googie on
Hi,

I'm trying to find out a way to get source code of dynamically
evaluated code, like below:

set a ""
foreach x {1 2 3} {
append a "puts $x\n"
}
append a "puts [info evalcode]"
eval $a

I need something like [info evalcode] above, which would return in
this case:

puts 1
puts 2
puts 3
puts [info evalcode]

Any similar way is acceptable. Some ideas?

Thanks!
Regards,
Googie
From: Alexandre Ferrieux on
On Jul 18, 9:38 pm, Googie <pawelsal...(a)gmail.com> wrote:
> Hi,
>
> I'm trying to find out a way to get source code of dynamically
> evaluated code, like below:
>
> set a ""
> foreach x {1 2 3} {
>         append a "puts $x\n"}
>
> append a "puts [info evalcode]"
> eval $a
>
> I need something like [info evalcode] above, which would return in
> this case:
>
> puts 1
> puts 2
> puts 3
> puts [info evalcode]
>
> Any similar way is acceptable. Some ideas?

(note that you must protect the [] with braces or individual
backslashes in this line:
append a {puts [info evalcode]}
)

If you accept adding a proc layer to the 'eval', then TIP 348's [info
errorstack] comes close to a solution (it is implemented in HEAD, so
it will be in 8.6b2):

proc ev x {uplevel 1 $x} ;# a "proc-ified eval"
set a {
puts 1
puts 2
puts 3
error BARF
}
catch {ev $a}
puts [info errorstack]

->

UP 1 CALL {ev {
puts 1
puts 2
puts 3
error BARF
}}

You can read the associated documentation in HEAD (see info.n, and
also catch.n, return.n), or you can have a look at the TIP itself:
http://www.tcl.tk/cgi-bin/tct/tip/348.html

-Alex




From: Googie on
Thanks Alexandre!

You inspired me to a very nice solution, basing on [rename] and [eval]
custom implementation:

# Implementation
rename eval eval.orig
proc eval {args} {
set ___very_unusual_variable_name___ $args
unset args
upvar args args
eval.orig {*}$___very_unusual_variable_name___
}

# Demo
set code {
puts "here's original \"args\" value: $args"
puts "and here's my eval code: eval
$___very_unusual_variable_name___"
}

proc proc1 {args} {
eval $::code
}

proc1 arg1 arg2
# End of demo

This is of course very first version of code that works. Now I'll polish it.
This is why I love Tcl ;)

Alexandre Ferrieux wrote:

> On Jul 18, 9:38 pm, Googie <pawelsal...(a)gmail.com> wrote:
>> Hi,
>>
>> I'm trying to find out a way to get source code of dynamically
>> evaluated code, like below:
>>
>> set a ""
>> foreach x {1 2 3} {
>> append a "puts $x\n"}
>>
>> append a "puts [info evalcode]"
>> eval $a
>>
>> I need something like [info evalcode] above, which would return in
>> this case:
>>
>> puts 1
>> puts 2
>> puts 3
>> puts [info evalcode]
>>
>> Any similar way is acceptable. Some ideas?
>
> (note that you must protect the [] with braces or individual
> backslashes in this line:
> append a {puts [info evalcode]}
> )
>
> If you accept adding a proc layer to the 'eval', then TIP 348's [info
> errorstack] comes close to a solution (it is implemented in HEAD, so
> it will be in 8.6b2):
>
> proc ev x {uplevel 1 $x} ;# a "proc-ified eval"
> set a {
> puts 1
> puts 2
> puts 3
> error BARF
> }
> catch {ev $a}
> puts [info errorstack]
>
> ->
>
> UP 1 CALL {ev {
> puts 1
> puts 2
> puts 3
> error BARF
> }}
>
> You can read the associated documentation in HEAD (see info.n, and
> also catch.n, return.n), or you can have a look at the TIP itself:
> http://www.tcl.tk/cgi-bin/tct/tip/348.html
>
> -Alex

--
Pozdrawiam! (Regards!)
Googie
From: Alexandre Ferrieux on
On Jul 19, 1:11 pm, Googie <n...(a)spam.0rg> wrote:
>
> You inspired me to a very nice solution, basing on [rename] and [eval]
> custom implementation:

Ah yes, instrumentation, if you can afford it...
Glad it inspired you despite being at 180 degrees ;-)

When you have a TIP everything looks like a nail :D

-Alex
From: tom.rmadilo on
On Jul 18, 12:38 pm, Googie <pawelsal...(a)gmail.com> wrote:
> Hi,
>
> I'm trying to find out a way to get source code of dynamically
> evaluated code, like below:
>
> set a ""
> foreach x {1 2 3} {
>         append a "puts $x\n"}
>
> append a "puts [info evalcode]"
> eval $a
>
> I need something like [info evalcode] above, which would return in
> this case:
>
> puts 1
> puts 2
> puts 3
> puts [info evalcode]

This is ridiculously simple:

puts $a

You have hit on a simple model: create code, store it in a variable,
or return it from a proc. Then you can either [puts] or [eval].

I like using a proc to create the code, but a script level variable is
just as effective, introspection only requires that you print out the
value of the variable holding the code.