Joel Uckelman on Sat, 30 Dec 2006 14:03:56 -0700 (MST)

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

[s-d] dice server testing

I've put up a new roller for you guys to test. Right now it's just calling
Perl's rand() to get random numbers; the real thing will poll my dice

You can find the test form here:

Text will be returned unchanged. Anything enclosed in {{ }} will be
evaluated by Perl using the Safe module.[1]

xdy will evaluate to the sum of x rolls of a y-sided die, and xDy will
evaluate to a list of x rolls of a y-sided die, but only if x and y
are constants. If you want x and y to be expressions instead of numbers,
e.g. d6 rolls of a d10, you need to call d or D as a two-argument function:

{{ 3d6 }}, but {{ d(d6,10) }}

d6 and D6 are the same is 1d6 and 1D6, respectively.

Any code chunk $code which contains neither ';' nor '}' will be automatically
be replaced by 'print join('', $code)' in order to save typing. For more
complex expressions, you have to issue print commands yourself.[2]

All code chunks are evaluated in the same sandbox. Global variables and
subroutines will persist from chunk to chunk:

{{ $x = 1 }} {{ $x }}

will print: 1 1

Local variables will not:

{{ my $x = 1 }} {{ $x }}

will produce you a warning about $x being uninitialized in the second chunk.

There is a special list @r which holds the output from each chunk, in case
you need to refer back to it.[3]

{{ $x = 1 }} {{ $r[0] }}

will print: 1 1 

Presently, I'm providing the following functions, in addition to the
Perl ones you can call:

d(x,y)         : returns sum of x rolls of a dy, same as sum(D(x,y))
D(x,y)         : returns list of x rolls of a dy
pick(list)     : returns one from list at random, same as choose(1,list)
choose(n,list) : returns n from a list at random, without replacement
max(list)      : returns greatest element from list
min(list)      : returns least element from list
sum(list)      : returns sum of elements from list
prod(list)     : returns product of elements from list
uniq(list)     : returns list of distinct elements from list
sortn(list)    : returns list sorted by numeric value
shuffle(list)  : returns shuffled list
count(list)    : returns size of list, same as scalar(list)

As for what Perl built-in functions you can call, if it's an IO, threading,
filesystem, database, or subprocess function, you can't call it.[4] Also,
I built in a process-time and memory consumption limit, so that you can't
accidentally or purposely DoS me.

So, I'd appreciate it if you guys would try this out and tell me what you
think. (Yes, there will be an email version too, but not just yet.) I'm
interested in how usable you find it, but I'd also like if you'd try to
break it and do things that you're not supposed to be able to do (like
breaking out of the sandbox).

The source is here, in case anyone wants to have a look:[5]

Also, here is the log so you can see what everyone else has tried:

A few examples:

Here are the first 19 Fibonnaci numbers: {{ 
$a = 0; 
$b = 1;
$i = 0;
print $a += $b, ' ' while print $b += $a, ' ' and $i++ < 9;

{{ pick 'Tom', 'Dick', 'Harry' }} falls in a pit.

Your battleship takes {{ print scalar(grep { $_ == 1 } 10D6) }} hit{{ print 's' if $r[9] != 1; }}.

{{ shuffle 1..52 }}

Here's a 10 x 10 grid of d6 rolls:

   for (1..20) {
      for (1..20) {
         print d6, ' ';
      print "\n";


1. Don't put }} in your code, as it will be interpreted as the end of
code mode. Also, don't put {{ in your text unless you intend to start
code mode.

2. This can be annoying for blocks like {{ count grep { $_ == 1 } 10d6 }},
which will have no output unless you append a 'print'. I'm not sure what
to do about this, since it's difficult to tell what's an expression and
what's not.
3. I used @r for "reference". If you can think of a better name, let
me know.

4. I.e., I intend for you not to be able to call it. Whether you actaully
can is another question.

5. If anyone knows of another way to capture the output of print statements
besides opening an in-memory file and calling select to switch default
filehandles, let me know. Surprisingly, it takes several MB of memory to do
it this way!

6. Would it be useful to wrap to 80 columns? Or to have an option for that?

spoon-discuss mailing list