summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrbgems/mruby-struct/src/struct.c24
-rw-r--r--mrbgems/mruby-struct/test/struct.rb5
-rw-r--r--mrbgems/mruby-symbol-ext/mrblib/symbol.rb2
-rw-r--r--mrblib/enum.rb2
4 files changed, 31 insertions, 2 deletions
diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c
index 121226717..a4d70ae1a 100644
--- a/mrbgems/mruby-struct/src/struct.c
+++ b/mrbgems/mruby-struct/src/struct.c
@@ -11,6 +11,7 @@
#include "mruby/string.h"
#include "mruby/class.h"
#include "mruby/variable.h"
+#include "mruby/hash.h"
#define RSTRUCT_LEN(st) RARRAY_LEN(st)
#define RSTRUCT_PTR(st) RARRAY_PTR(st)
@@ -806,6 +807,28 @@ mrb_struct_to_a(mrb_state *mrb, mrb_value self)
}
/*
+ * call-seq:
+ * struct.to_h -> hash
+ *
+ * Create a hash from member names and struct values.
+ */
+static mrb_value
+mrb_struct_to_h(mrb_state *mrb, mrb_value self)
+{
+ mrb_value members, ret;
+ mrb_int i;
+
+ members = mrb_struct_s_members(mrb, mrb_obj_value(mrb_class(mrb, self)));
+ ret = mrb_hash_new_capa(mrb, RARRAY_LEN(members));
+
+ for (i = 0; i < RARRAY_LEN(members); ++i) {
+ mrb_hash_set(mrb, ret, RARRAY_PTR(members)[i], RSTRUCT_PTR(self)[i]);
+ }
+
+ return ret;
+}
+
+/*
* A <code>Struct</code> is a convenient way to bundle a number of
* attributes together, using accessor methods, without having to write
* an explicit class.
@@ -842,6 +865,7 @@ mrb_mruby_struct_gem_init(mrb_state* mrb)
mrb_define_method(mrb, st, "length", mrb_struct_len, MRB_ARGS_NONE());
mrb_define_method(mrb, st, "to_a", mrb_struct_to_a, MRB_ARGS_NONE());
mrb_define_method(mrb, st, "values", mrb_struct_to_a, MRB_ARGS_NONE());
+ mrb_define_method(mrb, st, "to_h", mrb_struct_to_h, MRB_ARGS_NONE());
}
void
diff --git a/mrbgems/mruby-struct/test/struct.rb b/mrbgems/mruby-struct/test/struct.rb
index 01e3076a5..d654830ca 100644
--- a/mrbgems/mruby-struct/test/struct.rb
+++ b/mrbgems/mruby-struct/test/struct.rb
@@ -118,3 +118,8 @@ assert('Struct#to_a, Struct#values') do
assert_equal ['a', 'b'], s.to_a
assert_equal ['a', 'b'], s.values
end
+
+assert('Struct#to_h') do
+ s = Struct.new(:white, :red, :green).new('ruuko', 'yuzuki', 'hitoe')
+ assert_equal(:white => 'ruuko', :red => 'yuzuki', :green => 'hitoe') { s.to_h }
+end
diff --git a/mrbgems/mruby-symbol-ext/mrblib/symbol.rb b/mrbgems/mruby-symbol-ext/mrblib/symbol.rb
index f4bf23cb1..4cf18f647 100644
--- a/mrbgems/mruby-symbol-ext/mrblib/symbol.rb
+++ b/mrbgems/mruby-symbol-ext/mrblib/symbol.rb
@@ -3,7 +3,7 @@ class Symbol
def to_proc
->(obj,*args,&block) do
- obj.send(self, *args, &block)
+ obj.__send__(self, *args, &block)
end
end
diff --git a/mrblib/enum.rb b/mrblib/enum.rb
index 4f9682ac7..41fd97fe7 100644
--- a/mrblib/enum.rb
+++ b/mrblib/enum.rb
@@ -202,7 +202,7 @@ module Enumerable
raise ArgumentError, "too many arguments" if args.size > 2
if Symbol === args[-1]
sym = args[-1]
- block = ->(x,y){x.send(sym,y)}
+ block = ->(x,y){x.__send__(sym,y)}
args.pop
end
if args.empty?