Ruby eval and debugging revisited

| 1 Comment | No TrackBacks

In a previous entry I discussed debugging, and in particular printing the full contents of the stack. The tricky thing is to do so without affecting [ markers. At the moment I'm working on an alternative interpreter, which has required digging into the source of the official interpreter, as the only real spec.

The official syntax overview says that

' Strings and " strings are parsed using ruby's string parse, via eval. Therefore it is possible to run ruby code in GolfScript by doing something like this:

"The time is #{Time.now}" -> "The time is Tue Dec 11 12:59:27 -0500 2007"

This will probably be of little use, except for doing things that GolfScript does not have built-in, such as floating point arithmetic, etc.

What it doesn't describe in detail is the timing. Exploiting the eval call is slightly tricky.

Why? Because the call is made when the string is parsed. If you have a string enclosed in " directly in your program then it will be parsed before anything executes. As an example:

200000 .?;
"The time is #{Time.now}" puts
200000 .?;
"The time is #{Time.now}" puts
$ date ; golfscript.rb example.gs ; date
sáb oct 29 12:21:53 CEST 2011
The time is Sat Oct 29 12:21:53 +0200 2011
The time is Sat Oct 29 12:21:53 +0200 2011

sáb oct 29 12:22:00 CEST 2011

On my computer it takes about 3 seconds to do each exponentiation, but the times displayed are the same, and are the time when the program executed. In order to get the actual time you need to delay the parsing of the string, which seems to be most easily accomplished by wrapping it in ' and then compiling it with ~:

200000 .?;
'"The time is #{Time.now}"'~ puts
200000 .?;
'"The time is #{Time.now}"'~ puts
$ date ; golfscript.rb example2.gs ; date
sáb oct 29 12:22:57 CEST 2011
The time is Sat Oct 29 12:23:01 +0200 2011
The time is Sat Oct 29 12:23:01 +0200 2011

sáb oct 29 12:23:05 CEST 2011

This time the time taken for the first exponentiation can be seen. However, both times are still the same. When I first wrote this article I didn't know why, but I've worked it out and updated. It comes down to a little cache in golfscript.rb:

def var(name,val=nil)
	eval"#{s="$_#{$var_lookup[name]||=$var_lookup.size}"}||=val"
	s
end

The upshot of all this is that it's possible to exploit knowledge of the internals of the interpreter to get a better DEBUG routine, but we need to ensure that each string evaluated this way is unique (and to be aware that we're leaking memory!)

0:DBGID;
{['"#{$stderr.puts Garray.new($stack).ginspect.to_s.slice(1..-2)#'DBGID):DBGID'
}"']''*~;}:DEBUG;

This will print the entire stack to stderr without affecting the internal state (other than that cache) in any way.

No TrackBacks

TrackBack URL: http://www.cheddarmonk.org/golfscriptblog/cgi-bin/mt/mt-tb.cgi/5

1 Comment

y's string parse, via eval. Therefore it is possible to run ruby code in GolfScript by doing something like this:

"The time is #{Time.now}" -> "The time is Tue Dec 11 12:59:27 -0500 2007"
This will probably be of little use, except for doing things that GolfScript does not have built-in, such as floating point arithmetic, etc.

What it doesn't describe in detail is the timing. Exploiting the eval call is slightly tricky.

Why? Because the call is made when the string is parsed. If you h
dji
dji drones

Leave a comment

About this Entry

This page contains a single entry by Peter published on October 29, 2011 12:30 PM.

Code dissection: secret sharing was the previous entry in this blog.

Code dissection: polynomial extrapolation is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.