At the command line, that is.
Problem: When you run a .rb file from the
command line, you have to type a (potentially
lengthy) command.
First idea: Wrap it in a batch file.
However: Did you know that Windows is too dumb
to associate the stdout of a program with the
stdout of the batch file? I.e., if you have a
foo.bat file and you say “foo >outfile” it will
NOT work (at least not in older Windows versions…
I can’t speak of NT, 2K, XP).
Well, you can use “start” on Win98. Still kind of
a pain.
My solution:
Write a C program that will detect its own name and
directory; locate a corresponding Ruby program in
that same directory; read the #! line from the
beginning (usu. ignored in Win); and run the Ruby
program. It passes in the parameters, too.
Note that you only have to compile once, since the
program knows its own name. You can just
copy fakeruby.exe myprog.exe
assuming there is a myprog.rb in that directory.
I know, it’s kind of an exercise in futility. But
if you want the code, here it is. It compiles fine
with djgpp.
Feel free to criticize it or improve it. It’s far
from perfect. For some reason, execvp() didn’t work
for me.
Cheers,
Hal
···
==============================================
#include <assert.h>
#include <stdio.h>
#define LONG 512
main(int argc, char *argv[])
{
char file[LONG], *line, *rubyopts;
char *ext, *line1;
int name_len, i;
FILE *input;
char sysstr[LONG];
line = (char *) malloc(LONG);
rubyopts = (char *) malloc(LONG);
strcpy(file, argv[0]);
name_len = strlen(file);
ext = file + name_len - 3;
for (i=0; i<3; i++)
(ext+i) = toupper((ext+i));
assert(strcmp(ext,“EXE”)==0);
strcpy(ext-1,".rb");
input = fopen(file,“r”);
line1 = fgets(line,LONG,input);
/*!!! check error */
fclose(input);
strcpy(sysstr, "ruby ");
strcpy(args[0],file);
strcpy(argv[0],file);
for(i=1; i<argc; i++)
args[i]=argv[i];
args[argc] = NULL;
if (strncmp(line,"#!",2)==0) /* Found a #! line /
{
rubyopts = strstr(line,"ruby "); / may be null /
/ space is needed because ‘ruby’ may be earlier in
* the path… a tab found here will make it fail!!
*/
if (!rubyopts)
{
fprintf(stderr,"Warning: #! line does not contain 'ruby'\n");
strcpy(rubyopts,"");
}
else
{
rubyopts += 4; /* skip 'ruby' */
rubyopts[strlen(rubyopts)-1]='\0'; /* chomp! */
}
strcat(sysstr,rubyopts);
}
for (i=0; i<argc; i++)
{
strcat(sysstr," ");
strcat(sysstr,argv[i]);
}
/* Using system()… execvp() didn’t work on
- my machine, even with the proper terminating
- NULL pointer.
*/
system(sysstr);
/* Bad style – not freeing memory. */
}