summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--build_config.rb8
-rw-r--r--mrbgems/mruby-array-ext/mrblib/array.rb98
-rw-r--r--mrbgems/mruby-array-ext/test/array.rb79
-rw-r--r--mrbgems/mruby-enum-ext/mrblib/enum.rb79
-rw-r--r--mrbgems/mruby-enum-ext/test/enum.rb19
-rw-r--r--mrbgems/mruby-eval/mrbgem.rake4
-rw-r--r--mrbgems/mruby-eval/src/eval.c23
-rw-r--r--mrbgems/mruby-hash-ext/mrbgem.rake4
-rw-r--r--mrbgems/mruby-hash-ext/mrblib/hash.rb12
-rw-r--r--mrbgems/mruby-hash-ext/test/hash.rb20
10 files changed, 345 insertions, 1 deletions
diff --git a/build_config.rb b/build_config.rb
index d41c44b98..475ff27a8 100644
--- a/build_config.rb
+++ b/build_config.rb
@@ -35,9 +35,15 @@ MRuby::Build.new do |conf|
# Use extensional Array class
conf.gem "#{root}/mrbgems/mruby-array-ext"
+ # Use extensional Hash class
+ conf.gem "#{root}/mrbgems/mruby-hash-ext"
+
+ # No use eval method
+ # conf.gem "#{root}/mrbgems/mruby-eval
+
# Generate binaries
# conf.bins = %w(mrbc mruby mirb)
-
+
# C compiler settings
# conf.cc do |cc|
# cc.command = ENV['CC'] || 'gcc'
diff --git a/mrbgems/mruby-array-ext/mrblib/array.rb b/mrbgems/mruby-array-ext/mrblib/array.rb
new file mode 100644
index 000000000..b3ff9bfca
--- /dev/null
+++ b/mrbgems/mruby-array-ext/mrblib/array.rb
@@ -0,0 +1,98 @@
+class Array
+ def uniq!
+ ary = self.dup
+ result = []
+ while ary.size > 0
+ result << ary.shift
+ ary.delete(result.last)
+ end
+ if result.size == self.size
+ nil
+ else
+ self.replace(result)
+ end
+ end
+
+ def uniq
+ ary = self.dup
+ ary.uniq!
+ ary
+ end
+
+ def -(elem)
+ raise TypeError, "can't convert to Array" unless elem.class == Array
+
+ hash = {}
+ array = []
+ elem.each { |x| hash[x] = true }
+ self.each { |x| array << x unless hash[x] }
+ array
+ end
+
+ def |(elem)
+ raise TypeError, "can't convert to Array" unless elem.class == Array
+
+ ary = self + elem
+ ary.uniq! or ary
+ end
+
+ def &(elem)
+ raise TypeError, "can't convert to Array" unless elem.class == Array
+
+ hash = {}
+ array = []
+ elem.each{|v| hash[v] = true }
+ self.each do |v|
+ if hash[v]
+ array << v
+ hash.delete v
+ end
+ end
+ array
+ end
+
+ def flatten(depth=nil)
+ ar = []
+ self.each do |e|
+ if e.is_a?(Array) && (depth.nil? || depth > 0)
+ ar += e.flatten(depth.nil? ? nil : depth - 1)
+ else
+ ar << e
+ end
+ end
+ ar
+ end
+
+ def flatten!(depth=nil)
+ modified = false
+ ar = []
+ self.each do |e|
+ if e.is_a?(Array) && (depth.nil? || depth > 0)
+ ar += e.flatten(depth.nil? ? nil : depth - 1)
+ modified = true
+ else
+ ar << e
+ end
+ end
+ if modified
+ self.replace(ar)
+ else
+ nil
+ end
+ end
+
+ def compact
+ result = self.dup
+ result.compact!
+ result
+ end
+
+ def compact!
+ result = self.select { |e| e != nil }
+ if result.size == self.size
+ nil
+ else
+ self.replace(result)
+ end
+ end
+end
diff --git a/mrbgems/mruby-array-ext/test/array.rb b/mrbgems/mruby-array-ext/test/array.rb
index 36da6bb17..1c441cec4 100644
--- a/mrbgems/mruby-array-ext/test/array.rb
+++ b/mrbgems/mruby-array-ext/test/array.rb
@@ -28,3 +28,82 @@ assert("Array#rassoc") do
a.rassoc("four").nil?
end
+assert("Array#uniq!") do
+ a = [1, 2, 3, 1]
+ a.uniq!
+ a == [1, 2, 3]
+end
+
+assert("Array#uniq") do
+ a = [1, 2, 3, 1]
+ a.uniq == [1, 2, 3] && a == [1, 2, 3, 1]
+end
+
+assert("Array#-") do
+ a = [1, 2, 3, 1]
+ b = [1]
+ c = 1
+ e1 = nil
+
+ begin
+ a - c
+ rescue => e1
+ end
+
+ (a - b) == [2, 3] and e1.class == TypeError and a == [1, 2, 3, 1]
+end
+
+assert("Array#|") do
+ a = [1, 2, 3, 1]
+ b = [1, 4]
+ c = 1
+ e1 = nil
+
+ begin
+ a | c
+ rescue => e1
+ end
+
+ (a | b) == [1, 2, 3, 4] and e1.class == TypeError and a == [1, 2, 3, 1]
+end
+
+assert("Array#&") do
+ a = [1, 2, 3, 1]
+ b = [1, 4]
+ c = 1
+ e1 = nil
+
+ begin
+ a & c
+ rescue => e1
+ end
+
+ (a & b) == [1] and e1.class == TypeError and a == [1, 2, 3, 1]
+end
+
+assert("Array#flatten") do
+ [1, 2, "3", {4=>5}, :'6'] == [1, 2, "3", {4=>5}, :'6'].flatten and
+ [1, 2, 3, 4, 5, 6] == [1, 2, [3, 4, 5], 6].flatten and
+ [1, 2, 3, 4, 5, 6] == [1, 2, [3, [4, 5], 6]].flatten and
+ [1, [2, [3, [4, [5, [6]]]]]] == [1, [2, [3, [4, [5, [6]]]]]].flatten(0) and
+ [1, 2, [3, [4, [5, [6]]]]] == [1, [2, [3, [4, [5, [6]]]]]].flatten(1) and
+ [1, 2, 3, [4, [5, [6]]]] == [1, [2, [3, [4, [5, [6]]]]]].flatten(2) and
+ [1, 2, 3, 4, [5, [6]]] == [1, [2, [3, [4, [5, [6]]]]]].flatten(3) and
+ [1, 2, 3, 4, 5, [6]] == [1, [2, [3, [4, [5, [6]]]]]].flatten(4) and
+ [1, 2, 3, 4, 5, 6] == [1, [2, [3, [4, [5, [6]]]]]].flatten(5)
+end
+
+assert("Array#flatten!") do
+ [1, 2, 3, 4, 5, 6] == [1, 2, [3, [4, 5], 6]].flatten!
+end
+
+assert("Array#compact") do
+ a = [1, nil, "2", nil, :t, false, nil]
+ a.compact == [1, "2", :t, false] && a == [1, nil, "2", nil, :t, false, nil]
+end
+
+assert("Array#compact!") do
+ a = [1, nil, "2", nil, :t, false, nil]
+ a.compact!
+ a == [1, "2", :t, false]
+end
diff --git a/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mrbgems/mruby-enum-ext/mrblib/enum.rb
index a9545da98..f250d39f1 100644
--- a/mrbgems/mruby-enum-ext/mrblib/enum.rb
+++ b/mrbgems/mruby-enum-ext/mrblib/enum.rb
@@ -82,4 +82,83 @@ module Enumerable
ary
end
+ ##
+ # call-seq:
+ # enum.each_cons(n) {...} -> nil
+ #
+ # Iterates the given block for each array of consecutive <n>
+ # elements.
+ #
+ # e.g.:
+ # (1..10).each_cons(3) {|a| p a}
+ # # outputs below
+ # [1, 2, 3]
+ # [2, 3, 4]
+ # [3, 4, 5]
+ # [4, 5, 6]
+ # [5, 6, 7]
+ # [6, 7, 8]
+ # [7, 8, 9]
+ # [8, 9, 10]
+
+ def each_cons(n, &block)
+ raise TypeError, "expected Integer for 1st argument" unless n.kind_of? Integer
+ raise ArgumentError, "invalid size" if n <= 0
+
+ ary = []
+ self.each do |e|
+ ary.shift if ary.size == n
+ ary << e
+ block.call(ary.dup) if ary.size == n
+ end
+ end
+
+ ##
+ # call-seq:
+ # enum.each_slice(n) {...} -> nil
+ #
+ # Iterates the given block for each slice of <n> elements.
+ #
+ # e.g.:
+ # (1..10).each_slice(3) {|a| p a}
+ # # outputs below
+ # [1, 2, 3]
+ # [4, 5, 6]
+ # [7, 8, 9]
+ # [10]
+
+ def each_slice(n, &block)
+ raise TypeError, "expected Integer for 1st argument" unless n.kind_of? Integer
+ raise ArgumentError, "invalid slice size" if n <= 0
+
+ ary = []
+ self.each do |e|
+ ary << e
+ if ary.size == n
+ block.call(ary)
+ ary = []
+ end
+ end
+ block.call(ary) unless ary.empty?
+ end
+
+ ##
+ # call-seq:
+ # enum.group_by {| obj | block } -> a_hash
+ #
+ # Returns a hash, which keys are evaluated result from the
+ # block, and values are arrays of elements in <i>enum</i>
+ # corresponding to the key.
+ #
+ # (1..6).group_by {|i| i%3} #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
+
+ def group_by(&block)
+ h = {}
+ self.each do |e|
+ key = block.call(e)
+ h.key?(key) ? (h[key] << e) : (h[key] = [e])
+ end
+ h
+ end
+
end
diff --git a/mrbgems/mruby-enum-ext/test/enum.rb b/mrbgems/mruby-enum-ext/test/enum.rb
index 5fc9759ad..aa56cdf84 100644
--- a/mrbgems/mruby-enum-ext/test/enum.rb
+++ b/mrbgems/mruby-enum-ext/test/enum.rb
@@ -23,3 +23,22 @@ assert("Enumerable#take_while") do
assert_equal a.take_while {|i| i < 3 }, [1, 2]
end
+assert("Enumerable#each_cons") do
+ a = []
+ (1..5).each_cons(3){|e| a << e}
+ assert_equal a, [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
+end
+
+assert("Enumerable#each_slice") do
+ a = []
+ (1..10).each_slice(3){|e| a << e}
+ assert_equal a, [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
+end
+
+assert("Enumerable#group_by") do
+ r = (1..6).group_by {|i| i % 3 }
+ assert_equal r[0], [3, 6]
+ assert_equal r[1], [1, 4]
+ assert_equal r[2], [2, 5]
+end
+
diff --git a/mrbgems/mruby-eval/mrbgem.rake b/mrbgems/mruby-eval/mrbgem.rake
new file mode 100644
index 000000000..f80cf1b9e
--- /dev/null
+++ b/mrbgems/mruby-eval/mrbgem.rake
@@ -0,0 +1,4 @@
+MRuby::Gem::Specification.new('mruby-eval') do |spec|
+ spec.license = 'MIT'
+ spec.authors = 'mruby developers'
+end
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c
new file mode 100644
index 000000000..039558596
--- /dev/null
+++ b/mrbgems/mruby-eval/src/eval.c
@@ -0,0 +1,23 @@
+#include "mruby.h"
+#include "mruby/compile.h"
+
+static mrb_value
+f_eval(mrb_state *mrb, mrb_value self)
+{
+ char *s;
+ int len;
+
+ mrb_get_args(mrb, "s", &s, &len);
+ return mrb_load_nstring(mrb, s, len);
+}
+
+void
+mrb_mruby_eval_gem_init(mrb_state* mrb)
+{
+ mrb_define_class_method(mrb, mrb->kernel_module, "eval", f_eval, ARGS_REQ(1));
+}
+
+void
+mrb_mruby_eval_gem_final(mrb_state* mrb)
+{
+}
diff --git a/mrbgems/mruby-hash-ext/mrbgem.rake b/mrbgems/mruby-hash-ext/mrbgem.rake
new file mode 100644
index 000000000..3163c8c88
--- /dev/null
+++ b/mrbgems/mruby-hash-ext/mrbgem.rake
@@ -0,0 +1,4 @@
+MRuby::Gem::Specification.new('mruby-hash-ext') do |spec|
+ spec.license = 'MIT'
+ spec.authors = 'mruby developers'
+end
diff --git a/mrbgems/mruby-hash-ext/mrblib/hash.rb b/mrbgems/mruby-hash-ext/mrblib/hash.rb
new file mode 100644
index 000000000..3e1bac0a2
--- /dev/null
+++ b/mrbgems/mruby-hash-ext/mrblib/hash.rb
@@ -0,0 +1,12 @@
+class Hash
+ def merge!(other, &block)
+ if block
+ other.each_key{|k|
+ self[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k]
+ }
+ else
+ other.each_key{|k| self[k] = other[k]}
+ end
+ self
+ end
+end
diff --git a/mrbgems/mruby-hash-ext/test/hash.rb b/mrbgems/mruby-hash-ext/test/hash.rb
new file mode 100644
index 000000000..98eb313a4
--- /dev/null
+++ b/mrbgems/mruby-hash-ext/test/hash.rb
@@ -0,0 +1,20 @@
+##
+# Hash(Ext) Test
+
+assert('Hash#merge!') do
+ a = { 'abc_key' => 'abc_value', 'cba_key' => 'cba_value' }
+ b = { 'cba_key' => 'XXX', 'xyz_key' => 'xyz_value' }
+
+ result_1 = a.merge! b
+
+ a = { 'abc_key' => 'abc_value', 'cba_key' => 'cba_value' }
+ result_2 = a.merge!(b) do |key, original, new|
+ original
+ end
+
+ result_1 == {'abc_key' => 'abc_value', 'cba_key' => 'XXX',
+ 'xyz_key' => 'xyz_value' } and
+ result_2 == {'abc_key' => 'abc_value', 'cba_key' => 'cba_value',
+ 'xyz_key' => 'xyz_value' }
+end
+