Looks good, except for the segfaults. XD Still, there's something missing
there. You see, Dir#entries also fails to find the temporary directory temp
that the very same Dir.mkdir created in my original code. 
···
*****
NoMethodError raised!
private method `open' called for Dir:Class
*****
Errno::EEXIST raised!
File exists @ dir_s_mkdir - tmp
eval:1:in `mkdir'
*****
Does the 'tmp' directory exist? true
*****
NoMethodError raised!
undefined method `glob' for Dir:Class
*****
TypeError raised!
wrong argument type File (expected dir)
eval:1:in `entries'
*****
Does the 'tmp' directory still exist? true
*The Actual Code*
// main.cpp - Dir#glob Execution Test
#include <stdio.h>
#include <ruby.h>
#include <ruby/io.h>
#define str(s) rb_str_new_cstr(s)
VALUE call_exception(VALUE exc)
{
exc = rb_errinfo();
VALUE klass, msg, bt;
klass = str( rb_obj_classname(exc) );
klass = rb_str_plus(klass, str(" raised!"));
msg = rb_funcall(exc, rb_intern("message"), 0);
bt = rb_funcall(exc, rb_intern("backtrace"), 0);
rb_ary_pop(bt);
VALUE c_ary = { klass, msg, bt, str("*****") };
rb_io_puts(4, c_ary, rb_stdout);
rb_exc_raise(exc); // Ignored by Ruby...
rb_set_errinfo(Qnil);
return Qnil;
}
void raise_error(int status, const char* str)
{
VALUE exc = Qnil;
int exit_status;
rb_protect((VALUE (*)(VALUE))call_exception, exc, &exit_status);
}
int main(int argc, char **argv)
{
int rargc = 0, state = 0;
char **rargv = 0;
ruby_sysinit(&rargc, &rargv);
ruby_setup();
VALUE rversion = rb_const_get(rb_cObject, rb_intern("RUBY_VERSION"));
rb_funcall(Qnil, rb_intern("print"), 1, str("Ruby version: "));
rb_p( rversion );
rb_funcall(Qnil, rb_intern("puts"), 1,
str("Get working directory:"));
rb_p( rb_funcall(rb_cDir, rb_intern("getwd"), 0) );
const char* line_break = "*****\n";
const char *mk_dir = "Dir.mkdir('tmp')";
const char *is_tmp = "puts Dir.exist?('tmp')";
const char *glob = "puts Dir.glob('*.h')";
const char *entries = "puts Dir.entries('tmp')";
const char *rm_dir = "Dir.rmdir('tmp')";
printf(line_break);
rb_eval_string_protect("Dir.open('arch')", &state);
if (state) raise_error(state, "Dir#open");
rb_eval_string_protect(mk_dir, &state);
if (state) raise_error(state, "Dir#mkdir");
rb_funcall(Qnil, rb_intern("print"), 1,
str("Does the 'tmp' directory exist? "));
rb_eval_string(is_tmp);
printf(line_break);
rb_eval_string_protect(glob, &state);
if (state) raise_error(state, "Dir#glob");
rb_eval_string_protect(entries, &state);
if (state) raise_error(state, "Dir#entries");
//rb_eval_string(rm_dir);
rb_funcall(Qnil, rb_intern("print"), 1,
str("Does the 'tmp' directory still exist? "));
rb_eval_string(is_tmp);
ruby_cleanup(0);
return state;
}
On Thu, Oct 13, 2022, 06:47 Frank J. Cameron <fjc@fastmail.net> wrote:
Thanks for the code
I shortened it a bit to just show the problem:
#include <ruby.h>
#define str(s) rb_str_new_cstr(s)
int main(int argc, char **argv)
{
int rargc = 0, state = 0;
char **rargv = 0;
ruby_sysinit(&rargc, &rargv);
ruby_setup();
VALUE rversion = rb_const_get(rb_cObject, rb_intern("RUBY_VERSION"));
rb_funcall(Qnil, rb_intern("print"), 1, str("Ruby version: "));
rb_p( rversion );
rb_p( str("before glob") );
rb_eval_string("p Dir.glob('*.h')");
rb_p( str("after glob") );
ruby_cleanup(0);
return 0;
}
Results:
$ ./a.out-2.5
Ruby version: "2.5.8"
"before glob"
"after glob"
$ ./a.out-2.6
Ruby version: "2.6.9"
"before glob"
"after glob"
$ ./a.out-2.7
Ruby version: "2.7.6"
"before glob"
"after glob"
$ ./a.out-3.0
Ruby version: "3.0.4"
"before glob"
ruby: [BUG] Segmentation fault at 0x0000000000000018
...
$ ./a.out-3.1
Ruby version: "3.1.2"
"before glob"
ruby: [BUG] Segmentation fault at 0x0000000000000018
...
Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>