gvars 0.9.7 → 0.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/gvars/gvars.c +84 -86
- data/lib/gvars/version.rb +1 -1
- data/tmp.rb +41 -2
- metadata +1 -2
- data/ext/gvars/gvars.c-old +0 -147
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 837ffc167909e2abe16ff54fdcd7bfbe4cb6dc0346f1c3e9037b17933f3b89a7
|
|
4
|
+
data.tar.gz: 9e36c6847244b578e63032468c2d94e7fff4f4e05c68cd3a1c126fc257a02b7c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7e71e7a19371437156d14f1831045a6229b4fcd055cc82680309266c5ed20781ec030b78e591e38e4a7adb62633ceb98d5284ca69b8e40eb475ee4ea829ee269
|
|
7
|
+
data.tar.gz: f5cba137bad5f8d9db885f468df9bc147f89b7c0106653a409fd8aa5d32767a8fceba372b4a4c778bdf4161ae59c215dd2081cff250aeccfcf4c2c161658c1a9
|
data/ext/gvars/gvars.c
CHANGED
|
@@ -7,7 +7,7 @@ VALUE gvars_module;
|
|
|
7
7
|
//
|
|
8
8
|
// for checking, it makes that `name` starts with `$`. This isn't really required, as ruby supports
|
|
9
9
|
// globals that don't start with `$` (but doesn't expose any methods to interact with them)
|
|
10
|
-
static char *get_global_name(VALUE *name) {
|
|
10
|
+
static char *get_global_name(VALUE *name, bool raise) {
|
|
11
11
|
// If `name` is a symbol, get its backing string
|
|
12
12
|
if (RB_SYMBOL_P(*name)) {
|
|
13
13
|
*name = rb_sym2str(*name);
|
|
@@ -16,7 +16,7 @@ static char *get_global_name(VALUE *name) {
|
|
|
16
16
|
char *namestr = StringValueCStr(*name);
|
|
17
17
|
|
|
18
18
|
// Ensure it starts with a dollar sign
|
|
19
|
-
if (namestr[0] != '$') {
|
|
19
|
+
if (raise && namestr[0] != '$') {
|
|
20
20
|
rb_raise(rb_eNameError, "'%s' is not allowed as a global variable name", namestr);
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -27,13 +27,26 @@ static char *get_global_name(VALUE *name) {
|
|
|
27
27
|
static VALUE
|
|
28
28
|
gvars_f_global_variable_get(VALUE self, VALUE name)
|
|
29
29
|
{
|
|
30
|
-
return rb_gv_get(get_global_name(&name));
|
|
30
|
+
return rb_gv_get(get_global_name(&name, true));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static VALUE
|
|
34
|
+
gvars_f_global_variable_aref(VALUE self, VALUE name)
|
|
35
|
+
{
|
|
36
|
+
return rb_gv_get(get_global_name(&name, false));
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
static VALUE
|
|
34
40
|
gvars_f_global_variable_set(VALUE self, VALUE name, VALUE value)
|
|
35
41
|
{
|
|
36
|
-
return rb_gv_set(get_global_name(&name), value);
|
|
42
|
+
return rb_gv_set(get_global_name(&name, true), value);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
static VALUE
|
|
47
|
+
gvars_f_global_variable_aset(VALUE self, VALUE name, VALUE value)
|
|
48
|
+
{
|
|
49
|
+
return rb_gv_set(get_global_name(&name, false), value);
|
|
37
50
|
}
|
|
38
51
|
|
|
39
52
|
static VALUE
|
|
@@ -45,8 +58,8 @@ gvars_f_global_variables(VALUE self)
|
|
|
45
58
|
static VALUE
|
|
46
59
|
gvars_f_alias_global_variable(VALUE self, VALUE new, VALUE old)
|
|
47
60
|
{
|
|
48
|
-
ID newid = rb_intern(get_global_name(&new));
|
|
49
|
-
rb_alias_variable(newid, rb_intern(get_global_name(&old)));
|
|
61
|
+
ID newid = rb_intern(get_global_name(&new, true));
|
|
62
|
+
rb_alias_variable(newid, rb_intern(get_global_name(&old, true)));
|
|
50
63
|
return ID2SYM(newid);
|
|
51
64
|
}
|
|
52
65
|
|
|
@@ -64,7 +77,7 @@ gvars_f_each(VALUE self)
|
|
|
64
77
|
VALUE gvars = gvars_f_global_variables(self);
|
|
65
78
|
for (long i = 0; i < RARRAY_LEN(gvars); i++) {
|
|
66
79
|
VALUE key = RARRAY_AREF(gvars, i);
|
|
67
|
-
rb_yield(
|
|
80
|
+
rb_yield(rb_ary_new_from_args(2, key, gvars_f_global_variable_get(self, key)));
|
|
68
81
|
}
|
|
69
82
|
|
|
70
83
|
return self;
|
|
@@ -87,12 +100,13 @@ gvars_f_to_h(VALUE self)
|
|
|
87
100
|
struct value_ptr { VALUE *value; };
|
|
88
101
|
static void value_ptr_mark(void *ptr) { rb_gc_mark(*((struct value_ptr *) ptr)->value); }
|
|
89
102
|
static void value_ptr_free(void *ptr) { ruby_xfree(((struct value_ptr *) ptr)->value); }
|
|
103
|
+
static size_t value_ptr_size(const void *ptr) { return sizeof(struct value_ptr); }
|
|
90
104
|
static const rb_data_type_t value_ptr_data_type = {
|
|
91
105
|
.wrap_struct_name = "gvars/value_ptr",
|
|
92
106
|
.function = {
|
|
93
107
|
.dmark = value_ptr_mark,
|
|
94
108
|
.dfree = value_ptr_free,
|
|
95
|
-
.dsize =
|
|
109
|
+
.dsize = value_ptr_size,
|
|
96
110
|
},
|
|
97
111
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
98
112
|
};
|
|
@@ -104,21 +118,21 @@ struct gvars_virtual_var {
|
|
|
104
118
|
|
|
105
119
|
static void gvars_virtual_var_mark(void *ptr) {
|
|
106
120
|
struct gvars_virtual_var *gv = ptr;
|
|
107
|
-
|
|
121
|
+
rb_gc_mark(gv->backing);
|
|
108
122
|
rb_gc_mark(gv->getter);
|
|
109
123
|
rb_gc_mark(gv->setter);
|
|
110
124
|
}
|
|
111
125
|
|
|
112
|
-
static
|
|
113
|
-
|
|
126
|
+
static size_t gvars_virtual_var_size(const void *ptr) {
|
|
127
|
+
return sizeof(struct gvars_virtual_var);
|
|
114
128
|
}
|
|
115
129
|
|
|
116
130
|
static const rb_data_type_t gvars_type = {
|
|
117
|
-
.wrap_struct_name = "
|
|
131
|
+
.wrap_struct_name = "gvars/var",
|
|
118
132
|
.function = {
|
|
119
133
|
.dmark = gvars_virtual_var_mark,
|
|
120
|
-
.dfree =
|
|
121
|
-
.dsize =
|
|
134
|
+
.dfree = RUBY_DEFAULT_FREE,
|
|
135
|
+
.dsize = gvars_virtual_var_size,
|
|
122
136
|
},
|
|
123
137
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
124
138
|
};
|
|
@@ -127,61 +141,39 @@ static const rb_data_type_t gvars_type = {
|
|
|
127
141
|
static VALUE gvars_virtual_var_getter(ID id, VALUE *data) {
|
|
128
142
|
struct gvars_virtual_var *gv;
|
|
129
143
|
TypedData_Get_Struct(*data, struct gvars_virtual_var, &gvars_type, gv);
|
|
130
|
-
|
|
131
|
-
return rb_proc_call_kw(gv->getter, rb_ary_new(), RB_NO_KEYWORDS);
|
|
144
|
+
return rb_proc_call(gv->getter, rb_ary_new());
|
|
132
145
|
}
|
|
133
146
|
|
|
134
147
|
static void gvars_virtual_var_setter(VALUE val, ID id, VALUE *data) {
|
|
135
148
|
struct gvars_virtual_var *gv;
|
|
136
149
|
TypedData_Get_Struct(*data, struct gvars_virtual_var, &gvars_type, gv);
|
|
137
|
-
|
|
138
|
-
rb_proc_call_kw(gv->setter, rb_ary_new3(1, val), RB_NO_KEYWORDS);
|
|
150
|
+
rb_proc_call(gv->setter, rb_ary_new_from_args(1, val));
|
|
139
151
|
}
|
|
140
152
|
|
|
141
153
|
static VALUE gvars_hooked_state_var_getter(ID id, VALUE *data) {
|
|
142
154
|
struct gvars_virtual_var *gv;
|
|
143
155
|
TypedData_Get_Struct(*data, struct gvars_virtual_var, &gvars_type, gv);
|
|
144
|
-
|
|
145
|
-
return rb_proc_call_kw(gv->getter, rb_ary_new3(1, gv->backing), RB_NO_KEYWORDS);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
static void gvars_hooked_state_var_setter_noproc(VALUE val, ID id, VALUE *data) {
|
|
149
|
-
struct gvars_virtual_var *gv;
|
|
150
|
-
TypedData_Get_Struct(*data, struct gvars_virtual_var, &gvars_type, gv);
|
|
151
|
-
|
|
152
|
-
gv->backing = val;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
static void gvars_hooked_state_var_setter_proc(VALUE val, ID id, VALUE *data) {
|
|
156
|
-
struct gvars_virtual_var *gv;
|
|
157
|
-
TypedData_Get_Struct(*data, struct gvars_virtual_var, &gvars_type, gv);
|
|
158
|
-
|
|
159
|
-
gv->backing = rb_proc_call_kw(gv->setter, rb_ary_new3(2, val, gv->backing), RB_NO_KEYWORDS);
|
|
156
|
+
return rb_proc_call(gv->getter, rb_ary_new_from_args(1, gv->backing));
|
|
160
157
|
}
|
|
161
158
|
|
|
162
159
|
static VALUE gvars_hooked_initial_var_getter(ID id, VALUE *data) {
|
|
163
160
|
struct gvars_virtual_var *gv;
|
|
164
161
|
TypedData_Get_Struct(*data, struct gvars_virtual_var, &gvars_type, gv);
|
|
165
|
-
|
|
166
|
-
gv->backing = rb_proc_call_kw(gv->getter, rb_ary_new3(1, gv->backing), RB_NO_KEYWORDS);
|
|
167
|
-
return gv->backing;
|
|
162
|
+
return gv->backing = rb_proc_call(gv->getter, rb_ary_new_from_args(1, gv->backing));
|
|
168
163
|
}
|
|
169
164
|
|
|
170
|
-
static void
|
|
165
|
+
static void gvars_hooked_var_setter_noproc(VALUE val, ID id, VALUE *data) {
|
|
171
166
|
struct gvars_virtual_var *gv;
|
|
172
167
|
TypedData_Get_Struct(*data, struct gvars_virtual_var, &gvars_type, gv);
|
|
173
|
-
|
|
174
168
|
gv->backing = val;
|
|
175
169
|
}
|
|
176
170
|
|
|
177
|
-
static void
|
|
171
|
+
static void gvars_hooked_var_setter_proc(VALUE val, ID id, VALUE *data) {
|
|
178
172
|
struct gvars_virtual_var *gv;
|
|
179
173
|
TypedData_Get_Struct(*data, struct gvars_virtual_var, &gvars_type, gv);
|
|
180
|
-
|
|
181
|
-
gv->backing = rb_proc_call_kw(gv->setter, rb_ary_new3(2, val, gv->backing), RB_NO_KEYWORDS);
|
|
174
|
+
gv->backing = rb_proc_call(gv->setter, rb_ary_new_from_args(2, val, gv->backing));
|
|
182
175
|
}
|
|
183
176
|
|
|
184
|
-
|
|
185
177
|
static VALUE gvars_virtual_var_alloc(VALUE backing, VALUE getter, VALUE setter) {
|
|
186
178
|
struct gvars_virtual_var *gv;
|
|
187
179
|
VALUE gvar_ty = TypedData_Make_Struct(rb_cObject, struct gvars_virtual_var, &gvars_type, gv);
|
|
@@ -200,23 +192,7 @@ enum virtual_kind {
|
|
|
200
192
|
static void
|
|
201
193
|
gvars_define_virtual_method(VALUE self, VALUE *name, VALUE backing, VALUE getter, VALUE setter, enum virtual_kind kind, int readonly_special)
|
|
202
194
|
{
|
|
203
|
-
char *name_str = get_global_name(name);
|
|
204
|
-
VALUE getter_proc, setter_proc;
|
|
205
|
-
|
|
206
|
-
getter_proc = rb_convert_type(getter, T_DATA, "Proc", "to_proc");
|
|
207
|
-
if (NIL_P(getter_proc) || !rb_obj_is_proc(getter_proc)) {
|
|
208
|
-
rb_raise(rb_eTypeError, "wrong getter type %s (expected Proc)", rb_obj_classname(getter_proc));
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
if (NIL_P(setter)) {
|
|
212
|
-
setter_proc = Qnil;
|
|
213
|
-
} else {
|
|
214
|
-
setter_proc = rb_convert_type(setter, T_DATA, "Proc", "to_proc");
|
|
215
|
-
if (NIL_P(setter_proc) || !rb_obj_is_proc(setter_proc)) {
|
|
216
|
-
rb_raise(rb_eTypeError, "wrong setter type %s (expected Proc)", rb_obj_classname(setter_proc));
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
195
|
+
char *name_str = get_global_name(name, true);
|
|
220
196
|
struct value_ptr *vp;
|
|
221
197
|
VALUE vp_data = TypedData_Make_Struct(rb_cObject, struct value_ptr, &value_ptr_data_type, vp);
|
|
222
198
|
vp->value = RB_ALLOC(VALUE);
|
|
@@ -228,40 +204,51 @@ gvars_define_virtual_method(VALUE self, VALUE *name, VALUE backing, VALUE getter
|
|
|
228
204
|
switch (kind) {
|
|
229
205
|
case GVARS_VIRTUAL_KIND_VIRTUAL:
|
|
230
206
|
getter_meth = gvars_virtual_var_getter;
|
|
231
|
-
setter_meth =
|
|
232
|
-
break;
|
|
233
|
-
|
|
234
|
-
case GVARS_VIRTUAL_KIND_INITIAL:
|
|
235
|
-
getter_meth = gvars_hooked_initial_var_getter;
|
|
236
|
-
setter_meth = setter_proc == Qnil ? gvars_hooked_initial_var_setter_noproc : gvars_hooked_initial_var_setter_proc;
|
|
207
|
+
setter_meth = setter == Qnil ? rb_gvar_readonly_setter : gvars_virtual_var_setter;
|
|
237
208
|
break;
|
|
238
209
|
|
|
239
210
|
case GVARS_VIRTUAL_KIND_STATE:
|
|
240
|
-
|
|
241
|
-
|
|
211
|
+
case GVARS_VIRTUAL_KIND_INITIAL:
|
|
212
|
+
getter_meth = kind == GVARS_VIRTUAL_KIND_INITIAL ? gvars_hooked_initial_var_getter : gvars_hooked_state_var_getter;
|
|
213
|
+
if (readonly_special) setter_meth = rb_gvar_readonly_setter;
|
|
214
|
+
else setter_meth = setter == Qnil ? gvars_hooked_var_setter_noproc : gvars_hooked_var_setter_proc;
|
|
242
215
|
break;
|
|
243
216
|
|
|
244
217
|
default:
|
|
245
218
|
rb_bug("oops");
|
|
246
219
|
}
|
|
247
220
|
|
|
248
|
-
if (readonly_special) setter_meth = rb_gvar_readonly_setter;
|
|
249
221
|
|
|
250
222
|
rb_define_hooked_variable(name_str, vp->value, getter_meth, setter_meth);
|
|
251
223
|
|
|
252
|
-
VALUE hash = rb_iv_get(gvars_module, "
|
|
224
|
+
VALUE hash = rb_iv_get(gvars_module, "vars");
|
|
253
225
|
VALUE namesym = rb_str_new_cstr(name_str);
|
|
254
226
|
rb_hash_aset(hash, namesym, vp_data);
|
|
255
227
|
}
|
|
256
228
|
|
|
229
|
+
enum virtual_method_keywords {
|
|
230
|
+
VIRTUAL_METHOD_KEYWORDS_INITIAL,
|
|
231
|
+
VIRTUAL_METHOD_KEYWORDS_STATE,
|
|
232
|
+
VIRTUAL_METHOD_KEYWORDS_READONLY,
|
|
233
|
+
LENGTH_OF_VIRTUAL_METHOD_KEYWORDS,
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
static ID virtual_method_keyword_ids[LENGTH_OF_VIRTUAL_METHOD_KEYWORDS];
|
|
237
|
+
|
|
238
|
+
static VALUE convert_to_proc(const char *name, VALUE input) {
|
|
239
|
+
VALUE proc = rb_convert_type(input, T_DATA, "Proc", "to_proc");
|
|
240
|
+
|
|
241
|
+
if (NIL_P(proc) || !rb_obj_is_proc(proc)) {
|
|
242
|
+
rb_raise(rb_eTypeError, "wrong %s type %s (expected Proc)", name, rb_obj_classname(proc));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return proc;
|
|
246
|
+
}
|
|
247
|
+
|
|
257
248
|
static VALUE
|
|
258
249
|
gvars_f_define_virtual_method(int argc, VALUE *argv, VALUE self)
|
|
259
250
|
{
|
|
260
|
-
VALUE name, backing
|
|
261
|
-
ID keyword_ids[3];
|
|
262
|
-
keyword_ids[0] = rb_intern("initial");
|
|
263
|
-
keyword_ids[1] = rb_intern("state");
|
|
264
|
-
keyword_ids[2] = rb_intern("readonly");
|
|
251
|
+
VALUE name, backing, getter, setter, opts_hash, opts[LENGTH_OF_VIRTUAL_METHOD_KEYWORDS];
|
|
265
252
|
|
|
266
253
|
switch (rb_scan_args(argc, argv, "12:", &name, &getter, &setter, &opts_hash)) {
|
|
267
254
|
case 1:
|
|
@@ -281,22 +268,28 @@ gvars_f_define_virtual_method(int argc, VALUE *argv, VALUE self)
|
|
|
281
268
|
rb_bug("oops");
|
|
282
269
|
}
|
|
283
270
|
|
|
271
|
+
getter = convert_to_proc("getter", getter);
|
|
272
|
+
if (!NIL_P(setter)) setter = convert_to_proc("setter", setter);
|
|
273
|
+
|
|
284
274
|
enum virtual_kind kind = GVARS_VIRTUAL_KIND_VIRTUAL;
|
|
285
|
-
rb_get_kwargs(opts_hash,
|
|
275
|
+
rb_get_kwargs(opts_hash, virtual_method_keyword_ids, 0, LENGTH_OF_VIRTUAL_METHOD_KEYWORDS, opts);
|
|
286
276
|
|
|
287
|
-
if (opts[
|
|
288
|
-
if (opts[
|
|
277
|
+
if (opts[VIRTUAL_METHOD_KEYWORDS_INITIAL] != Qundef) {
|
|
278
|
+
if (opts[VIRTUAL_METHOD_KEYWORDS_STATE] != Qundef) {
|
|
289
279
|
rb_raise(rb_eArgError, "only one of 'initial' or 'state' may be supplied");
|
|
290
280
|
}
|
|
291
|
-
backing = opts[
|
|
281
|
+
backing = opts[VIRTUAL_METHOD_KEYWORDS_INITIAL];
|
|
292
282
|
kind = GVARS_VIRTUAL_KIND_INITIAL;
|
|
293
|
-
} else if (opts[
|
|
294
|
-
backing = opts[
|
|
283
|
+
} else if (opts[VIRTUAL_METHOD_KEYWORDS_STATE] != Qundef) {
|
|
284
|
+
backing = opts[VIRTUAL_METHOD_KEYWORDS_STATE];
|
|
295
285
|
kind = GVARS_VIRTUAL_KIND_STATE;
|
|
286
|
+
} else {
|
|
287
|
+
backing = Qnil;
|
|
296
288
|
}
|
|
297
289
|
|
|
298
|
-
|
|
299
|
-
|
|
290
|
+
// sadly no bool expected :-/
|
|
291
|
+
bool is_readonly = opts[VIRTUAL_METHOD_KEYWORDS_READONLY] != Qundef && RTEST(opts[VIRTUAL_METHOD_KEYWORDS_READONLY]);
|
|
292
|
+
if (is_readonly) {
|
|
300
293
|
if (setter != Qnil) {
|
|
301
294
|
rb_raise(rb_eArgError, "'readonly: true' may not be supplied when a setter proc is supplied");
|
|
302
295
|
}
|
|
@@ -314,7 +307,11 @@ void
|
|
|
314
307
|
Init_gvars(void)
|
|
315
308
|
{
|
|
316
309
|
gvars_module = rb_define_module("GVars");
|
|
317
|
-
rb_ivar_set(gvars_module, rb_intern("
|
|
310
|
+
rb_ivar_set(gvars_module, rb_intern("vars"), rb_hash_new());
|
|
311
|
+
|
|
312
|
+
virtual_method_keyword_ids[VIRTUAL_METHOD_KEYWORDS_INITIAL] = rb_intern("initial");
|
|
313
|
+
virtual_method_keyword_ids[VIRTUAL_METHOD_KEYWORDS_STATE] = rb_intern("state");
|
|
314
|
+
virtual_method_keyword_ids[VIRTUAL_METHOD_KEYWORDS_READONLY] = rb_intern("readonly");
|
|
318
315
|
|
|
319
316
|
// Define module-level functions that can be used as mixins
|
|
320
317
|
rb_define_module_function(gvars_module, "global_variable_get", gvars_f_global_variable_get, 1);
|
|
@@ -332,12 +329,13 @@ Init_gvars(void)
|
|
|
332
329
|
rb_define_singleton_method(gvars_module, "each", gvars_f_each, 0);
|
|
333
330
|
rb_define_singleton_method(gvars_module, "to_h", gvars_f_to_h, 0);
|
|
334
331
|
|
|
332
|
+
rb_define_singleton_method(gvars_module, "[]", gvars_f_global_variable_aref, 1);
|
|
333
|
+
rb_define_singleton_method(gvars_module, "[]=", gvars_f_global_variable_aset, 2);
|
|
334
|
+
|
|
335
335
|
// Aliases
|
|
336
336
|
VALUE gvars_singleton = rb_singleton_class(gvars_module);
|
|
337
337
|
rb_define_alias(gvars_singleton, "get", "global_variable_get");
|
|
338
|
-
rb_define_alias(gvars_singleton, "[]", "global_variable_get");
|
|
339
338
|
rb_define_alias(gvars_singleton, "set", "global_variable_set");
|
|
340
|
-
rb_define_alias(gvars_singleton, "[]=", "global_variable_set");
|
|
341
339
|
rb_define_alias(gvars_singleton, "alias", "alias_global_variable");
|
|
342
340
|
rb_define_alias(gvars_singleton, "list", "global_variables");
|
|
343
341
|
rb_define_alias(gvars_singleton, "virtual", "define_virtual_method");
|
data/lib/gvars/version.rb
CHANGED
data/tmp.rb
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
require 'gvars'
|
|
2
2
|
p GVars::VERSION
|
|
3
3
|
|
|
4
|
+
require 'optparse'
|
|
5
|
+
OptParse.new do |op|
|
|
6
|
+
op.on '--timeout=X', 'the timeout'
|
|
7
|
+
op.parse %w[--timeout 34.5], into: GVars
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
p $timeout
|
|
11
|
+
|
|
12
|
+
__END__
|
|
13
|
+
h = {}
|
|
14
|
+
GVars.virtual(:$-e, &h.method(:[]).curry(1).<<(:$-e))
|
|
15
|
+
# GVars.virtual(:$-e,) { $-W.to_s }
|
|
16
|
+
# $-v = false
|
|
17
|
+
# p $-e
|
|
18
|
+
# $-v = true
|
|
19
|
+
# p $-e
|
|
20
|
+
# $-v = nil
|
|
21
|
+
p $-e
|
|
22
|
+
|
|
23
|
+
exit
|
|
24
|
+
|
|
4
25
|
100.times do
|
|
5
26
|
GVars.virtual(:$foo) { p "bar" }
|
|
6
27
|
# GVars.virtual(:$foo) { p "foo" }
|
|
@@ -20,8 +41,26 @@ fail unless 11 == $bar1
|
|
|
20
41
|
|
|
21
42
|
GVars.virtual(:$bar2, state: 'a') { it.succ!.dup }
|
|
22
43
|
fail unless ['b', 'c', 'd'] == [$bar2, $bar2, $bar2]
|
|
23
|
-
|
|
24
|
-
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
GVars.virtual(:$lol) { @x = 3 }
|
|
47
|
+
class Thing
|
|
48
|
+
def doit
|
|
49
|
+
$lol
|
|
50
|
+
p @x
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
Thing.new.doit
|
|
54
|
+
p @x
|
|
55
|
+
trace_var :$bar, proc {|v| puts "$_ is now '#{v}'" }
|
|
56
|
+
$bar = 2
|
|
57
|
+
$bar = 3
|
|
58
|
+
trace_var :$_, proc {|v| puts "$_ is now '#{v}'" }
|
|
59
|
+
$_ = "hello"
|
|
60
|
+
$_ = ' there'
|
|
61
|
+
|
|
62
|
+
# $bar2 = 10
|
|
63
|
+
# fail unless 11 == $bar2
|
|
25
64
|
|
|
26
65
|
# GVars.virtual(:$bar, proc{ p "bar" })
|
|
27
66
|
# GVars.virtual(:$baz, proc{ p "bar" }, proc { p "baz: #{_1}"})
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gvars
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sam Westerman
|
|
@@ -24,7 +24,6 @@ files:
|
|
|
24
24
|
- Rakefile
|
|
25
25
|
- ext/gvars/extconf.rb
|
|
26
26
|
- ext/gvars/gvars.c
|
|
27
|
-
- ext/gvars/gvars.c-old
|
|
28
27
|
- gb
|
|
29
28
|
- lib/gvars.rb
|
|
30
29
|
- lib/gvars/version.rb
|
data/ext/gvars/gvars.c-old
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
#include "ruby.h"
|
|
2
|
-
|
|
3
|
-
// Converts `name` to a global variable name, ensures it's valid, and returns it.
|
|
4
|
-
//
|
|
5
|
-
// for checking, it makes that `name` starts with `$`. This isn't really required, as ruby supports
|
|
6
|
-
// globals that don't start with `$` (but doesn't expose any methods to interact with them)
|
|
7
|
-
static char *get_global_name(VALUE *name) {
|
|
8
|
-
// printf("spot1\n");
|
|
9
|
-
if (RB_SYMBOL_P(*name)) *name = rb_sym2str(*name);
|
|
10
|
-
// printf("spot2\n");
|
|
11
|
-
char *namestr = StringValueCStr(*name);
|
|
12
|
-
// printf("spot3\n");
|
|
13
|
-
|
|
14
|
-
if (namestr[0] != '$') {
|
|
15
|
-
rb_raise(rb_eNameError, "'%s' is not allowed as a global variable name", namestr);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return namestr;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
static VALUE
|
|
22
|
-
gvars_f_get(VALUE self, VALUE name)
|
|
23
|
-
{
|
|
24
|
-
// extern VALUE rb_gvars_get(ID);
|
|
25
|
-
return rb_gvars_get(rb_intern(get_global_name(&name)));
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
static VALUE
|
|
29
|
-
gvars_f_set(VALUE self, VALUE name, VALUE value)
|
|
30
|
-
{
|
|
31
|
-
return rb_gv_set(get_global_name(&name), value);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
static VALUE
|
|
35
|
-
gvars_f_defined_p(VALUE self, VALUE name)
|
|
36
|
-
{
|
|
37
|
-
extern VALUE rb_gvar_defined(ID);
|
|
38
|
-
return rb_gvar_defined(rb_check_id(&name));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
static VALUE
|
|
42
|
-
gvars_list(VALUE self)
|
|
43
|
-
{
|
|
44
|
-
return rb_f_global_variables();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
static VALUE
|
|
48
|
-
gvars_f_alias(VALUE self, VALUE new, VALUE old)
|
|
49
|
-
{
|
|
50
|
-
ID newid = rb_intern(get_global_name(&new));
|
|
51
|
-
rb_alias_variable(newid, rb_intern(get_global_name(&old)));
|
|
52
|
-
return ID2SYM(newid);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
struct hooked_var {
|
|
56
|
-
VALUE getter, setter;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
static VALUE hooked_var_getter(ID id, VALUE *data) {
|
|
60
|
-
struct hooked_var *bv = (struct hooked_var *)data;
|
|
61
|
-
return rb_proc_call_kw(bv->getter, rb_ary_new3(1, rb_id2str(id)), RB_NO_KEYWORDS);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
static void hooked_var_setter(VALUE val, ID id, VALUE *data) {
|
|
65
|
-
struct hooked_var *bv = (struct hooked_var *)data;
|
|
66
|
-
rb_proc_call_kw(bv->setter, rb_ary_new3(2, rb_id2str(id), val), RB_NO_KEYWORDS);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
static VALUE
|
|
70
|
-
gvars_define_virtual_global(int argc, VALUE *argv, VALUE self)
|
|
71
|
-
{
|
|
72
|
-
VALUE name, getter, setter;
|
|
73
|
-
|
|
74
|
-
switch (rb_scan_args(argc, argv, "12", &name, &getter, &setter)) {
|
|
75
|
-
case 1:
|
|
76
|
-
getter = (rb_need_block(), rb_block_proc());
|
|
77
|
-
setter = Qnil;
|
|
78
|
-
break;
|
|
79
|
-
|
|
80
|
-
case 2:
|
|
81
|
-
setter = Qnil;
|
|
82
|
-
|
|
83
|
-
case 3:
|
|
84
|
-
if (rb_block_given_p()) {
|
|
85
|
-
rb_warn("given block not used");
|
|
86
|
-
}
|
|
87
|
-
break;
|
|
88
|
-
default:
|
|
89
|
-
rb_bug("oops");
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
char *name_str = get_global_name(&name);
|
|
93
|
-
|
|
94
|
-
VALUE getter_proc, setter_proc;
|
|
95
|
-
|
|
96
|
-
getter_proc = rb_convert_type(getter, T_DATA, "Proc", "to_proc");
|
|
97
|
-
if (NIL_P(getter_proc) || !rb_obj_is_proc(getter_proc)) {
|
|
98
|
-
rb_raise(rb_eTypeError, "wrong getter type %s (expected Proc)", rb_obj_classname(getter_proc));
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (NIL_P(setter)) {
|
|
102
|
-
setter_proc = Qnil;
|
|
103
|
-
} else {
|
|
104
|
-
setter_proc = rb_convert_type(setter, T_DATA, "Proc", "to_proc");
|
|
105
|
-
if (NIL_P(setter_proc) || !rb_obj_is_proc(setter_proc)) {
|
|
106
|
-
rb_raise(rb_eTypeError, "wrong setter type %s (expected Proc)", rb_obj_classname(setter_proc));
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// todo: not just leak memory here lol
|
|
111
|
-
struct hooked_var *hv = (struct hooked_var *)malloc(sizeof(struct hooked_var));
|
|
112
|
-
hv->getter = getter_proc;
|
|
113
|
-
hv->setter = setter_proc;
|
|
114
|
-
|
|
115
|
-
rb_define_hooked_variable(name_str, (VALUE *)hv, hooked_var_getter, setter_proc == Qnil ? rb_gvar_readonly_setter : hooked_var_setter);
|
|
116
|
-
extern void rb_gvar_ractor_local(const char *);
|
|
117
|
-
rb_gvar_ractor_local(name_str);
|
|
118
|
-
return name; //TODO: ID2SYM(id)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
VALUE gvars_module;
|
|
122
|
-
|
|
123
|
-
void
|
|
124
|
-
Init_gvars(void)
|
|
125
|
-
{
|
|
126
|
-
gvars_module = rb_define_module("GVars");
|
|
127
|
-
|
|
128
|
-
// Define module-level functions that can be used as mixins
|
|
129
|
-
rb_define_module_function(gvars_module, "global_variable_get", gvars_f_get, 1);
|
|
130
|
-
rb_define_module_function(gvars_module, "global_variable_set", gvars_f_set, 2);
|
|
131
|
-
// rb_define_module_function(gvars_module, "global_variable_defined?", gvars_f_defined_p, 1);
|
|
132
|
-
rb_define_module_function(gvars_module, "alias_global_variable", gvars_f_alias, 2);
|
|
133
|
-
|
|
134
|
-
// Don't make mixin, as it exists in Kernel
|
|
135
|
-
rb_define_singleton_method(gvars_module, "global_variables", gvars_list, 0);
|
|
136
|
-
|
|
137
|
-
// aliases at top-level
|
|
138
|
-
rb_define_alias(rb_singleton_class(gvars_module), "get", "global_variable_get");
|
|
139
|
-
rb_define_alias(rb_singleton_class(gvars_module), "set", "global_variable_set");
|
|
140
|
-
// rb_define_alias(rb_singleton_class(gvars_module), "defined?", "global_variable_defined?");
|
|
141
|
-
rb_define_alias(rb_singleton_class(gvars_module), "alias", "alias_global_variable");
|
|
142
|
-
rb_define_alias(rb_singleton_class(gvars_module), "list", "global_variables");
|
|
143
|
-
rb_define_alias(rb_singleton_class(gvars_module), "[]", "global_variable_get");
|
|
144
|
-
rb_define_alias(rb_singleton_class(gvars_module), "[]=", "global_variable_set");
|
|
145
|
-
|
|
146
|
-
// rb_define_singleton_method(gvars_module, "virtual", gvars_define_virtual_global, -1);
|
|
147
|
-
}
|