3#include "eval_intern.h"
5#include "internal/class.h"
6#include "internal/eval.h"
7#include "internal/error.h"
8#include "internal/file.h"
9#include "internal/gc.h"
10#include "internal/hash.h"
11#include "internal/load.h"
12#include "internal/namespace.h"
13#include "internal/st.h"
14#include "internal/variable.h"
24VALUE rb_cNamespaceEntry = 0;
25VALUE rb_mNamespaceLoader = 0;
38static bool tmp_dir_has_dirsep;
40#define NAMESPACE_TMP_PREFIX "_ruby_ns_"
43# define MAXPATHLEN 1024
52bool ruby_namespace_enabled =
false;
53bool ruby_namespace_init_done =
false;
54bool ruby_namespace_crashed =
false;
60rb_namespace_init_done(
void)
62 ruby_namespace_init_done =
true;
66rb_root_namespace(
void)
68 return root_namespace;
72rb_main_namespace(
void)
74 return main_namespace;
78rb_current_namespace(
void)
88 return root_namespace;
90 return rb_vm_current_namespace(GET_EC());
94rb_loading_namespace(
void)
97 return root_namespace;
99 return rb_vm_loading_namespace(GET_EC());
103rb_current_namespace_in_crash_report(
void)
105 if (ruby_namespace_crashed)
107 return rb_current_namespace();
110static long namespace_id_counter = 0;
113namespace_generate_id(
void)
117 id = ++namespace_id_counter;
123namespace_main_to_s(
VALUE obj)
141 ns->expanded_load_path =
rb_ary_dup(root->expanded_load_path);
143 ns->load_path_check_cache = 0;
144 ns->loaded_features =
rb_ary_dup(root->loaded_features);
146 ns->loaded_features_index = st_init_numtable();
147 ns->loaded_features_realpaths = rb_hash_dup(root->loaded_features_realpaths);
148 ns->loaded_features_realpath_map = rb_hash_dup(root->loaded_features_realpath_map);
149 ns->loading_table = st_init_strtable();
150 ns->ruby_dln_libmap = rb_hash_new_with_size(0);
151 ns->gvar_tbl = rb_hash_new_with_size(0);
154 ns->is_optional =
true;
158rb_namespace_gc_update_references(
void *ptr)
164 ns->ns_object = rb_gc_location(ns->ns_object);
166 ns->top_self = rb_gc_location(ns->top_self);
167 ns->load_path = rb_gc_location(ns->load_path);
168 ns->expanded_load_path = rb_gc_location(ns->expanded_load_path);
169 ns->load_path_snapshot = rb_gc_location(ns->load_path_snapshot);
170 if (ns->load_path_check_cache) {
171 ns->load_path_check_cache = rb_gc_location(ns->load_path_check_cache);
173 ns->loaded_features = rb_gc_location(ns->loaded_features);
174 ns->loaded_features_snapshot = rb_gc_location(ns->loaded_features_snapshot);
175 ns->loaded_features_realpaths = rb_gc_location(ns->loaded_features_realpaths);
176 ns->loaded_features_realpath_map = rb_gc_location(ns->loaded_features_realpath_map);
177 ns->ruby_dln_libmap = rb_gc_location(ns->ruby_dln_libmap);
178 ns->gvar_tbl = rb_gc_location(ns->gvar_tbl);
182rb_namespace_entry_mark(
void *ptr)
187 rb_gc_mark(ns->ns_object);
188 rb_gc_mark(ns->top_self);
189 rb_gc_mark(ns->load_path);
190 rb_gc_mark(ns->expanded_load_path);
191 rb_gc_mark(ns->load_path_snapshot);
192 rb_gc_mark(ns->load_path_check_cache);
193 rb_gc_mark(ns->loaded_features);
194 rb_gc_mark(ns->loaded_features_snapshot);
195 rb_gc_mark(ns->loaded_features_realpaths);
196 rb_gc_mark(ns->loaded_features_realpath_map);
197 if (ns->loading_table) {
198 rb_mark_tbl(ns->loading_table);
200 rb_gc_mark(ns->ruby_dln_libmap);
201 rb_gc_mark(ns->gvar_tbl);
205free_loading_table_entry(st_data_t key, st_data_t value, st_data_t arg)
212free_loaded_feature_index_i(st_data_t key, st_data_t value, st_data_t arg)
215 rb_darray_free((
void *)value);
221namespace_root_free(
void *ptr)
224 if (ns->loading_table) {
225 st_foreach(ns->loading_table, free_loading_table_entry, 0);
226 st_free_table(ns->loading_table);
227 ns->loading_table = 0;
230 if (ns->loaded_features_index) {
231 st_foreach(ns->loaded_features_index, free_loaded_feature_index_i, 0);
232 st_free_table(ns->loaded_features_index);
237namespace_entry_free(
void *ptr)
239 namespace_root_free(ptr);
244namespace_entry_memsize(
const void *ptr)
248 rb_st_memsize(ns->loaded_features_index) + \
249 rb_st_memsize(ns->loading_table);
255 rb_namespace_entry_mark,
256 namespace_entry_free,
257 namespace_entry_memsize,
258 rb_namespace_gc_update_references,
260 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
266 rb_namespace_entry_mark,
268 namespace_entry_memsize,
269 rb_namespace_gc_update_references,
271 &rb_namespace_data_type, 0, RUBY_TYPED_FREE_IMMEDIATELY
275rb_namespace_entry_alloc(
VALUE klass)
279 namespace_entry_initialize(entry);
284get_namespace_struct_internal(
VALUE entry)
292rb_get_namespace_t(
VALUE namespace)
295 ID id_namespace_entry;
297 VM_ASSERT(
namespace);
299 if (
NIL_P(
namespace))
300 return root_namespace;
302 VM_ASSERT(NAMESPACE_OBJ_P(
namespace));
304 CONST_ID(id_namespace_entry,
"__namespace_entry__");
305 entry = rb_attr_get(
namespace, id_namespace_entry);
306 return get_namespace_struct_internal(entry);
312 VM_ASSERT(ns && ns->ns_object);
313 return ns->ns_object;
323namespace_initialize(
VALUE namespace)
328 ID id_namespace_entry;
329 CONST_ID(id_namespace_entry,
"__namespace_entry__");
331 if (!rb_namespace_available()) {
332 rb_raise(
rb_eRuntimeError,
"Namespace is disabled. Set RUBY_NAMESPACE=1 environment variable to use Namespace.");
336 ns = get_namespace_struct_internal(entry);
338 ns->ns_object =
namespace;
339 ns->ns_id = namespace_generate_id();
345 RCLASS_SET_PRIME_CLASSEXT_WRITABLE(
namespace,
true);
349 object_classext = RCLASS_EXT_WRITABLE_IN_NS(rb_cObject, ns);
350 RCLASS_SET_CONST_TBL(
namespace, RCLASSEXT_CONST_TBL(object_classext),
true);
364rb_namespace_s_getenabled(
VALUE recv)
366 return RBOOL(rb_namespace_available());
378rb_namespace_s_current(
VALUE recv)
382 if (!rb_namespace_available())
385 ns = rb_vm_current_namespace(GET_EC());
386 VM_ASSERT(ns && ns->ns_object);
387 return ns->ns_object;
397rb_namespace_load_path(
VALUE namespace)
399 VM_ASSERT(NAMESPACE_OBJ_P(
namespace));
400 return rb_get_namespace_t(
namespace)->load_path;
404UINT rb_w32_system_tmpdir(WCHAR *path, UINT
len);
409system_default_tmpdir(
void)
413 WCHAR tmppath[_MAX_PATH];
414 UINT
len = rb_w32_system_tmpdir(tmppath, numberof(tmppath));
416 int blen = WideCharToMultiByte(CP_UTF8, 0, tmppath,
len, NULL, 0, NULL, NULL);
417 char *tmpdir =
xmalloc(blen + 1);
418 WideCharToMultiByte(CP_UTF8, 0, tmppath,
len, tmpdir, blen, NULL, NULL);
422#elif defined _CS_DARWIN_USER_TEMP_DIR
423 char path[MAXPATHLEN];
424 size_t len = confstr(_CS_DARWIN_USER_TEMP_DIR, path,
sizeof(path));
427 if (
len >
sizeof(path)) {
428 confstr(_CS_DARWIN_USER_TEMP_DIR, tmpdir,
len);
431 memcpy(tmpdir, path,
len);
440check_tmpdir(
const char *dir)
444 if (!dir)
return FALSE;
445 if (stat(dir, &st))
return FALSE;
447# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
449 if (!S_ISDIR(st.st_mode))
return FALSE;
454 if (st.st_mode & S_IWOTH) {
456 if (!(st.st_mode & S_ISVTX))
return FALSE;
461 if (access(dir, W_OK))
return FALSE;
470# define RETURN_ENV(name) \
471 if (check_tmpdir(tmpdir = getenv(name))) return ruby_strdup(tmpdir)
472 RETURN_ENV(
"TMPDIR");
474 tmpdir = system_default_tmpdir();
475 if (check_tmpdir(tmpdir))
return tmpdir;
483sprint_ext_filename(
char *str,
size_t size,
long namespace_id,
const char *prefix,
const char *basename)
485 if (tmp_dir_has_dirsep) {
486 return snprintf(str, size,
"%s%sp%"PRI_PIDT_PREFIX"u_%ld_%s", tmp_dir, prefix, getpid(), namespace_id, basename);
488 return snprintf(str, size,
"%s%s%sp%"PRI_PIDT_PREFIX"u_%ld_%s", tmp_dir, DIRSEP, prefix, getpid(), namespace_id, basename);
493copy_ext_file_error(
char *message,
size_t size)
495 int error = GetLastError();
497 size_t len = snprintf(message, size,
"%d: ", error);
499#define format_message(sublang) FormatMessage(\
500 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, \
501 NULL, error, MAKELANGID(LANG_NEUTRAL, (sublang)), \
502 message + len, size - len, NULL)
503 if (format_message(SUBLANG_ENGLISH_US) == 0)
504 format_message(SUBLANG_DEFAULT);
505 for (p = message +
len; *p; p++) {
506 if (*p ==
'\n' || *p ==
'\r')
513copy_ext_file_error(
char *message,
size_t size,
int copy_retvalue,
char *src_path,
char *dst_path)
515 switch (copy_retvalue) {
517 snprintf(message, size,
"can't open the extension path: %s", src_path);
519 snprintf(message, size,
"can't open the file to write: %s", dst_path);
521 snprintf(message, size,
"failed to read the extension path: %s", src_path);
523 snprintf(message, size,
"failed to write the extension path: %s", dst_path);
525 snprintf(message, size,
"failed to stat the extension path to copy permissions: %s", src_path);
527 snprintf(message, size,
"failed to set permissions to the copied extension path: %s", dst_path);
529 rb_bug(
"unknown return value of copy_ext_file: %d", copy_retvalue);
536copy_ext_file(
char *src_path,
char *dst_path)
541 WCHAR *w_src = rb_w32_mbstr_to_wstr(CP_UTF8, src_path, -1, NULL);
542 WCHAR *w_dst = rb_w32_mbstr_to_wstr(CP_UTF8, dst_path, -1, NULL);
543 if (!w_src || !w_dst) {
547 rvalue = CopyFileW(w_src, w_dst, FALSE) ? 0 : 1;
554 size_t read = 0, wrote, written = 0;
555 size_t maxread =
sizeof(buffer);
560 src = fopen(src_path,
"rb");
564 dst = fopen(dst_path,
"wb");
570 read = fread(buffer, 1,
sizeof(buffer), src);
574 wrote = fwrite(buffer+written, 1, read-written, dst);
575 if (wrote < read-written) {
589 if (read < maxread) {
590 if (clean_read && feof(src)) {
594 else if (ferror(src)) {
603#if defined(__CYGWIN__)
608 if (stat(src_path, &st) != 0) {
611 else if (chmod(dst_path, st.st_mode & 0777) != 0) {
620#if defined __CYGWIN__ || defined DOSISH
621#define isdirsep(x) ((x) == '/' || (x) == '\\')
623#define isdirsep(x) ((x) == '/')
626#define IS_SOEXT(e) (strcmp((e), ".so") == 0 || strcmp((e), ".o") == 0)
627#define IS_DLEXT(e) (strcmp((e), DLEXT) == 0)
630fname_without_suffix(
const char *fname,
char *rvalue,
size_t rsize)
632 size_t len = strlen(fname);
634 for (pos = fname +
len; pos > fname; pos--) {
635 if (IS_SOEXT(pos) || IS_DLEXT(pos)) {
639 if (fname +
len - pos > DLEXT_MAXLEN)
break;
641 if (
len > rsize - 1)
len = rsize - 1;
642 memcpy(rvalue, fname,
len);
647escaped_basename(
const char *path,
const char *fname,
char *rvalue,
size_t rsize)
650 const char *leaf = path, *found;
652 while ((found = strstr(leaf + 1, fname)) != NULL) {
655 strlcpy(rvalue, leaf, rsize);
656 for (pos = rvalue; *pos; pos++) {
657 if (isdirsep(*pos)) {
666 char ext_path[MAXPATHLEN], fname2[MAXPATHLEN], basename[MAXPATHLEN];
667 int copy_error, wrote;
668 char *src_path = RSTRING_PTR(path), *fname_ptr = RSTRING_PTR(fname);
671 fname_without_suffix(fname_ptr, fname2,
sizeof(fname2));
672 escaped_basename(src_path, fname2, basename,
sizeof(basename));
674 wrote = sprint_ext_filename(ext_path,
sizeof(ext_path), ns->ns_id, NAMESPACE_TMP_PREFIX, basename);
675 if (wrote >= (
int)
sizeof(ext_path)) {
676 rb_bug(
"Extension file path in namespace was too long");
678 copy_error = copy_ext_file(src_path, ext_path);
682 copy_ext_file_error(message,
sizeof(message));
684 copy_ext_file_error(message,
sizeof(message), copy_error, src_path, ext_path);
686 rb_raise(
rb_eLoadError,
"can't prepare the extension file for namespaces (%s from %s): %s", ext_path, src_path, message);
697rb_namespace_load(
int argc,
VALUE *argv,
VALUE namespace)
702 rb_vm_frame_flag_set_ns_require(GET_EC());
704 VALUE args = rb_ary_new_from_args(2, fname, wrap);
705 return rb_load_entrypoint(args);
709rb_namespace_require(
VALUE namespace,
VALUE fname)
711 rb_vm_frame_flag_set_ns_require(GET_EC());
717rb_namespace_require_relative(
VALUE namespace,
VALUE fname)
719 rb_vm_frame_flag_set_ns_require(GET_EC());
721 return rb_require_relative_entrypoint(fname);
725initialize_root_namespace(
void)
727 VALUE root_namespace, entry;
728 ID id_namespace_entry;
735 root->load_path_check_cache = 0;
740 root->loaded_features_index = st_init_numtable();
741 root->loaded_features_realpaths = rb_hash_new();
743 root->loaded_features_realpath_map = rb_hash_new();
746 root->ruby_dln_libmap = rb_hash_new_with_size(0);
747 root->gvar_tbl = rb_hash_new_with_size(0);
749 vm->root_namespace = root;
751 if (rb_namespace_available()) {
752 CONST_ID(id_namespace_entry,
"__namespace_entry__");
755 RCLASS_SET_PRIME_CLASSEXT_WRITABLE(root_namespace,
true);
756 RCLASS_SET_CONST_TBL(root_namespace, RCLASSEXT_CONST_TBL(RCLASS_EXT_PRIME(rb_cObject)),
true);
758 root->ns_id = namespace_generate_id();
759 root->ns_object = root_namespace;
762 rb_ivar_set(root_namespace, id_namespace_entry, entry);
766 root->ns_object =
Qnil;
783 return rb_iseq_eval(iseq, ns);
786static int namespace_experimental_warned = 0;
789rb_initialize_main_namespace(
void)
795 VM_ASSERT(rb_namespace_available());
797 if (!namespace_experimental_warned) {
799 "Namespace is experimental, and the behavior may change in the future!\n"
800 "See doc/namespace.md for known issues, etc.");
801 namespace_experimental_warned = 1;
805 VM_ASSERT(NAMESPACE_OBJ_P(main_ns));
806 ns = rb_get_namespace_t(main_ns);
807 ns->ns_object = main_ns;
809 ns->is_optional =
false;
813 vm->main_namespace = main_namespace = ns;
816 RCLASS_EXT_WRITABLE_IN_NS(rb_cObject, ns);
820rb_namespace_inspect(
VALUE obj)
828 ns = rb_get_namespace_t(obj);
831 if (NAMESPACE_ROOT_P(ns)) {
834 if (NAMESPACE_USER_P(ns)) {
837 if (NAMESPACE_MAIN_P(ns)) {
840 else if (NAMESPACE_OPTIONAL_P(ns)) {
848rb_namespace_loading_func(
int argc,
VALUE *argv,
VALUE _self)
850 rb_vm_frame_flag_set_ns_require(GET_EC());
855namespace_define_loader_method(
const char *name)
862Init_root_namespace(
void)
864 root_namespace->loading_table = st_init_strtable();
868Init_enable_namespace(
void)
870 const char *env = getenv(
"RUBY_NAMESPACE");
871 if (env && strlen(env) == 1 && env[0] ==
'1') {
872 ruby_namespace_enabled =
true;
875 ruby_namespace_init_done =
true;
883rb_namespace_s_root(
VALUE recv)
885 return root_namespace->ns_object;
890rb_namespace_s_main(
VALUE recv)
892 return main_namespace->ns_object;
896classname(
VALUE klass)
902 p = RCLASSEXT_CLASSPATH(RCLASS_EXT_PRIME(klass));
904 return RSTRING_PTR(p);
906 return "AnyClassValue";
907 return "NonClassValue";
910static enum rb_id_table_iterator_result
911dump_classext_methods_i(
ID mid,
VALUE _val,
void *data)
915 return ID_TABLE_CONTINUE;
918static enum rb_id_table_iterator_result
919dump_classext_constants_i(
ID mid,
VALUE _val,
void *data)
923 return ID_TABLE_CONTINUE;
933 snprintf(buf, 4096,
"Namespace %ld:%s classext %p\n",
934 RCLASSEXT_NS(ext)->ns_id, is_prime ?
" prime" :
"", (void *)ext);
937 snprintf(buf, 2048,
" Super: %s\n", classname(RCLASSEXT_SUPER(ext)));
940 tbl = RCLASSEXT_M_TBL(ext);
943 rb_id_table_foreach(RCLASSEXT_M_TBL(ext), dump_classext_methods_i, (
void *)ary);
945 snprintf(buf, 4096,
" Methods(%ld): ",
RARRAY_LEN(ary));
954 tbl = RCLASSEXT_CONST_TBL(ext);
957 rb_id_table_foreach(tbl, dump_classext_constants_i, (
void *)ary);
959 snprintf(buf, 4096,
" Constants(%ld): ",
RARRAY_LEN(ary));
994 snprintf(buf, 2048,
"Non-class/module value: %p (%s)\n", (
void *)klass, rb_type_str(
BUILTIN_TYPE(klass)));
999 snprintf(buf, 2048,
"Class: %p (%s)%s\n",
1000 (
void *)klass, classname(klass), RCLASS_SINGLETON_P(klass) ?
" [singleton]" :
"");
1003 snprintf(buf, 2048,
"Module: %p (%s)\n", (
void *)klass, classname(klass));
1007 ext = RCLASS_EXT_PRIME(klass);
1008 ns = RCLASSEXT_NS(ext);
1009 snprintf(buf, 2048,
"Prime classext namespace(%ld,%s), readable(%s), writable(%s)\n",
1011 NAMESPACE_ROOT_P(ns) ?
"root" : (NAMESPACE_MAIN_P(ns) ?
"main" :
"optional"),
1012 RCLASS_PRIME_CLASSEXT_READABLE_P(klass) ?
"t" :
"f",
1013 RCLASS_PRIME_CLASSEXT_WRITABLE_P(klass) ?
"t" :
"f");
1016 classext_tbl = RCLASS_CLASSEXT_TBL(klass);
1017 if (!classext_tbl) {
1021 snprintf(buf, 2048,
"Non-prime classexts: %zu\n", st_table_size(classext_tbl));
1025 rb_class_classext_foreach(klass, dump_classext_i, (
void *)res);
1032rb_namespace_root_p(
VALUE namespace)
1035 return RBOOL(NAMESPACE_ROOT_P(ns));
1040rb_namespace_main_p(
VALUE namespace)
1043 return RBOOL(NAMESPACE_MAIN_P(ns));
1048rb_namespace_user_p(
VALUE namespace)
1051 return RBOOL(NAMESPACE_USER_P(ns));
1066 tmp_dir = system_tmpdir();
1067 tmp_dir_has_dirsep = (strcmp(tmp_dir + (strlen(tmp_dir) - strlen(DIRSEP)), DIRSEP) == 0);
1076 initialize_root_namespace();
1080 namespace_define_loader_method(
"require");
1081 namespace_define_loader_method(
"require_relative");
1082 namespace_define_loader_method(
"load");
1084 if (rb_namespace_available()) {
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
#define rb_define_global_function(mid, func, arity)
Defines rb_mKernel #mid.
Ruby-level global variables / constants, visible from C.
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
VALUE rb_singleton_class(VALUE obj)
Finds or creates the singleton class of the passed object.
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_define_module_under(VALUE outer, const char *name)
Defines a module under the namespace of outer.
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Retrieves argument from argc and argv to given VALUE references according to the format string.
#define rb_str_new2
Old name of rb_str_new_cstr.
#define xfree
Old name of ruby_xfree.
#define xmalloc
Old name of ruby_xmalloc.
#define T_MODULE
Old name of RUBY_T_MODULE.
#define T_ICLASS
Old name of RUBY_T_ICLASS.
#define LONG2NUM
Old name of RB_LONG2NUM.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define NIL_P
Old name of RB_NIL_P.
#define T_CLASS
Old name of RUBY_T_CLASS.
#define BUILTIN_TYPE
Old name of RB_BUILTIN_TYPE.
#define FIXNUM_P
Old name of RB_FIXNUM_P.
#define CONST_ID
Old name of RUBY_CONST_ID.
void rb_category_warn(rb_warning_category_t category, const char *fmt,...)
Identical to rb_category_warning(), except it reports unless $VERBOSE is nil.
VALUE rb_eLoadError
LoadError exception.
VALUE rb_eRuntimeError
RuntimeError exception.
@ RB_WARN_CATEGORY_EXPERIMENTAL
Warning is for experimental features.
VALUE rb_cNamespace
Namespace class.
VALUE rb_obj_alloc(VALUE klass)
Allocates an instance of the given class.
VALUE rb_class_new_instance(int argc, const VALUE *argv, VALUE klass)
Allocates, then initialises an instance of the given class.
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
VALUE rb_class_new_instance_pass_kw(int argc, const VALUE *argv, VALUE klass)
Identical to rb_class_new_instance(), except it passes the passed keywords if any to the #initialize ...
VALUE rb_cModule
Module class.
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
VALUE rb_call_super(int argc, const VALUE *argv)
This resembles ruby's super.
VALUE rb_ary_dup(VALUE ary)
Duplicates an array.
VALUE rb_ary_new(void)
Allocates a new, empty array.
VALUE rb_ary_new_capa(long capa)
Identical to rb_ary_new(), except it additionally specifies how many rooms of objects it should alloc...
VALUE rb_ary_hidden_new(long capa)
Allocates a hidden (no class) empty array.
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
VALUE rb_ary_sort_bang(VALUE ary)
Destructively sorts the passed array in-place, according to each elements' <=> result.
VALUE rb_ary_join(VALUE ary, VALUE sep)
Recursively stringises the elements of the passed array, flattens that result, then joins the sequenc...
VALUE rb_require_string(VALUE feature)
Finds and loads the given feature, if absent.
VALUE rb_str_concat(VALUE dst, VALUE src)
Identical to rb_str_append(), except it also accepts an integer as a codepoint.
#define rb_str_cat_cstr(buf, str)
Identical to rb_str_cat(), except it assumes the passed pointer is a pointer to a C string.
#define rb_str_new_cstr(str)
Identical to rb_str_new, except it assumes the passed pointer is a pointer to a C string.
VALUE rb_ivar_set(VALUE obj, ID name, VALUE val)
Identical to rb_iv_set(), except it accepts the name as an ID instead of a C string.
void rb_const_set(VALUE space, ID name, VALUE val)
Names a constant.
void rb_define_alloc_func(VALUE klass, rb_alloc_func_t func)
Sets the allocator function of a class.
int len
Length of the buffer.
char * ruby_strdup(const char *str)
This is our own version of strdup(3) that uses ruby_xmalloc() instead of system malloc (benefits our ...
#define PRI_PIDT_PREFIX
A rb_sprintf() format prefix to be used for a pid_t parameter.
#define RARRAY_LEN
Just another name of rb_array_len.
#define StringValue(v)
Ensures that the parameter object is a String.
#define TypedData_Get_Struct(obj, type, data_type, sval)
Obtains a C struct from inside of a wrapper Ruby object.
#define TypedData_Wrap_Struct(klass, data_type, sval)
Converts sval, a pointer to your struct, into a Ruby object.
#define TypedData_Make_Struct(klass, type, data_type, sval)
Identical to TypedData_Wrap_Struct, except it allocates a new data region internally instead of takin...
#define RTEST
This is an old name of RB_TEST.
This is the struct that holds necessary info for a struct.
Internal header for Namespace.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
uintptr_t VALUE
Type that represents a Ruby object.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.