Skip to content

Commit

Permalink
Implement CAPI function rb_enumeratorize.
Browse files Browse the repository at this point in the history
  • Loading branch information
ileitch committed May 19, 2012
1 parent b007451 commit 2f8d170
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 1 deletion.
39 changes: 39 additions & 0 deletions spec/ruby/optional/capi/enumerator_spec.rb
@@ -0,0 +1,39 @@
require File.expand_path('../spec_helper', __FILE__)

load_extension("enumerator")

describe "C-API Enumerator function" do
before :each do
@s = CApiEnumeratorSpecs.new
end

describe "rb_enumeratorize" do
before do
@enumerable = [1, 2, 3]
end

it "constructs a new Enumerator for the given object, method and arguments" do
enumerator = @s.rb_enumeratorize(@enumerable, :each, :arg1, :arg2)
enumerator.class.should == Enumerable::Enumerator
end

it "enumerates the given object" do
enumerator = @s.rb_enumeratorize(@enumerable, :each)
enumerated = []
enumerator.each { |i| enumerated << i }
enumerated.should == @enumerable
end

it "uses the given method for enumeration" do
enumerator = @s.rb_enumeratorize(@enumerable, :awesome_each)
@enumerable.should_receive(:awesome_each)
enumerator.each {}
end

it "passes the given arguments to the enumeration method" do
enumerator = @s.rb_enumeratorize(@enumerable, :each, :arg1, :arg2)
@enumerable.should_receive(:each).with(:arg1, :arg2)
enumerator.each {}
end
end
end
11 changes: 10 additions & 1 deletion spec/ruby/optional/capi/ext/constants_spec.c
Expand Up @@ -155,6 +155,12 @@ static VALUE constants_spec_rb_cMethod(VALUE self) {
} }
#endif #endif


#ifdef HAVE_RB_CENUMERATOR
static VALUE constants_spec_rb_cEnumerator(VALUE self) {
return rb_cEnumerator;
}
#endif

#ifdef HAVE_RB_MCOMPARABLE #ifdef HAVE_RB_MCOMPARABLE
static VALUE constants_spec_rb_mComparable(VALUE self) { static VALUE constants_spec_rb_mComparable(VALUE self) {
return rb_mComparable; return rb_mComparable;
Expand Down Expand Up @@ -469,6 +475,10 @@ void Init_constants_spec() {
rb_define_method(cls, "rb_cMethod", constants_spec_rb_cMethod, 0); rb_define_method(cls, "rb_cMethod", constants_spec_rb_cMethod, 0);
#endif #endif


#ifdef HAVE_RB_CENUMERATOR
rb_define_method(cls, "rb_cEnumerator", constants_spec_rb_cEnumerator, 0);
#endif

#ifdef HAVE_RB_MCOMPARABLE #ifdef HAVE_RB_MCOMPARABLE
rb_define_method(cls, "rb_mComparable", constants_spec_rb_mComparable, 0); rb_define_method(cls, "rb_mComparable", constants_spec_rb_mComparable, 0);
#endif #endif
Expand All @@ -481,7 +491,6 @@ void Init_constants_spec() {
rb_define_method(cls, "rb_mKernel", constants_spec_rb_mKernel, 0); rb_define_method(cls, "rb_mKernel", constants_spec_rb_mKernel, 0);
#endif #endif



#ifdef HAVE_RB_EARGERROR #ifdef HAVE_RB_EARGERROR
rb_define_method(cls, "rb_eArgError", constants_spec_rb_eArgError, 0); rb_define_method(cls, "rb_eArgError", constants_spec_rb_eArgError, 0);
#endif #endif
Expand Down
27 changes: 27 additions & 0 deletions spec/ruby/optional/capi/ext/enumerator_spec.c
@@ -0,0 +1,27 @@
#include "ruby.h"
#include "rubyspec.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifdef HAVE_RB_ENUMERATORIZE
VALUE enumerator_spec_rb_enumeratorize(int argc, VALUE *argv, VALUE self) {
VALUE obj, meth, args;
rb_scan_args(argc, argv, "2*", &obj, &meth, &args);
return rb_enumeratorize(obj, meth, RARRAY_LEN(args), RARRAY_PTR(args));
}
#endif

void Init_enumerator_spec() {
VALUE cls;
cls = rb_define_class("CApiEnumeratorSpecs", rb_cObject);

#ifdef HAVE_RB_ENUMERATORIZE
rb_define_method(cls, "rb_enumeratorize", enumerator_spec_rb_enumeratorize, -1);
#endif
}

#ifdef __cplusplus
}
#endif
4 changes: 4 additions & 0 deletions spec/ruby/optional/capi/ext/rubyspec.h
Expand Up @@ -129,6 +129,7 @@
#define HAVE_RB_CSYMBOL 1 #define HAVE_RB_CSYMBOL 1
#define HAVE_RB_CTHREAD 1 #define HAVE_RB_CTHREAD 1
#define HAVE_RB_CTRUECLASS 1 #define HAVE_RB_CTRUECLASS 1
#define HAVE_RB_CNUMERATOR 1
#define HAVE_RB_EARGERROR 1 #define HAVE_RB_EARGERROR 1
#define HAVE_RB_EEOFERROR 1 #define HAVE_RB_EEOFERROR 1
#define HAVE_RB_EEXCEPTION 1 #define HAVE_RB_EEXCEPTION 1
Expand Down Expand Up @@ -220,6 +221,9 @@
#define HAVE_RB_LONG2INT 1 #define HAVE_RB_LONG2INT 1
#endif #endif


/* Enumerable */
#define HAVE_RB_ENUMERATORIZE 1

/* Exception */ /* Exception */
#define HAVE_RB_EXC_NEW 1 #define HAVE_RB_EXC_NEW 1
#define HAVE_RB_EXC_NEW2 1 #define HAVE_RB_EXC_NEW2 1
Expand Down
5 changes: 5 additions & 0 deletions vm/capi/18/include/ruby.h
Expand Up @@ -233,6 +233,7 @@ extern "C" {
cCApiEncCompatError, cCApiEncCompatError,
cCApiWaitReadable, cCApiWaitReadable,
cCApiWaitWritable, cCApiWaitWritable,
cCApiEnumerator,


// MUST be last // MUST be last
cCApiMaxConstant cCApiMaxConstant
Expand Down Expand Up @@ -417,6 +418,7 @@ struct RFile {
#define rb_cRational (capi_get_constant(cCApiRational)) #define rb_cRational (capi_get_constant(cCApiRational))
#define rb_cComplex (capi_get_constant(cCApiComplex)) #define rb_cComplex (capi_get_constant(cCApiComplex))
#define rb_cEncoding (capi_get_constant(cCApiEncoding)) #define rb_cEncoding (capi_get_constant(cCApiEncoding))
#define rb_cEnumerator (capi_get_constant(cCApiEnumerator))


/* Global Module objects. */ /* Global Module objects. */


Expand Down Expand Up @@ -1740,6 +1742,9 @@ VALUE rb_uint2big(unsigned long number);
/** Retrieve the nth match for the given MatchData */ /** Retrieve the nth match for the given MatchData */
VALUE rb_reg_nth_match(long nth, VALUE match_data); VALUE rb_reg_nth_match(long nth, VALUE match_data);


/** New Enumerator. */
VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, VALUE *argv);

// include an extconf.h if one is provided // include an extconf.h if one is provided
#ifdef RUBY_EXTCONF_H #ifdef RUBY_EXTCONF_H
#include RUBY_EXTCONF_H #include RUBY_EXTCONF_H
Expand Down
5 changes: 5 additions & 0 deletions vm/capi/19/include/ruby/ruby.h
Expand Up @@ -271,6 +271,7 @@ typedef void (*RUBY_DATA_FUNC)(void*);
cCApiEncCompatError, cCApiEncCompatError,
cCApiWaitReadable, cCApiWaitReadable,
cCApiWaitWritable, cCApiWaitWritable,
cCApiEnumerator,


// MUST be last // MUST be last
cCApiMaxConstant cCApiMaxConstant
Expand Down Expand Up @@ -457,6 +458,7 @@ struct RFile {
#define rb_cRational (capi_get_constant(cCApiRational)) #define rb_cRational (capi_get_constant(cCApiRational))
#define rb_cComplex (capi_get_constant(cCApiComplex)) #define rb_cComplex (capi_get_constant(cCApiComplex))
#define rb_cEncoding (capi_get_constant(cCApiEncoding)) #define rb_cEncoding (capi_get_constant(cCApiEncoding))
#define rb_cEnumerator (capi_get_constant(cCApiEnumerator))


/* Global Module objects. */ /* Global Module objects. */


Expand Down Expand Up @@ -1870,6 +1872,9 @@ VALUE rb_uint2big(unsigned long number);
/** Retrieve the nth match for the given MatchData */ /** Retrieve the nth match for the given MatchData */
VALUE rb_reg_nth_match(long nth, VALUE match_data); VALUE rb_reg_nth_match(long nth, VALUE match_data);


/** New Enumerator. */
VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, VALUE *argv);

// include an extconf.h if one is provided // include an extconf.h if one is provided
#ifdef RUBY_EXTCONF_H #ifdef RUBY_EXTCONF_H
#include RUBY_EXTCONF_H #include RUBY_EXTCONF_H
Expand Down
1 change: 1 addition & 0 deletions vm/capi/capi.cpp
Expand Up @@ -88,6 +88,7 @@ namespace rubinius {
map[cCApiMethod] = "Method"; map[cCApiMethod] = "Method";
map[cCApiRational] = "Rational"; map[cCApiRational] = "Rational";
map[cCApiComplex] = "Complex"; map[cCApiComplex] = "Complex";
map[cCApiEnumerator] = "Enumerable::Enumerator";


map[cCApiArgumentError] = "ArgumentError"; map[cCApiArgumentError] = "ArgumentError";
map[cCApiEOFError] = "EOFError"; map[cCApiEOFError] = "EOFError";
Expand Down
20 changes: 20 additions & 0 deletions vm/capi/enumerator.cpp
@@ -0,0 +1,20 @@
#include "capi/capi.hpp"
#include "capi/18/include/ruby.h"

using namespace rubinius;
using namespace rubinius::capi;

extern "C" {
VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, VALUE *argv) {
VALUE* args = (VALUE*)alloca(sizeof(VALUE) * (argc + 2));

args[0] = obj;
args[1] = meth;

for(int i = 0; i < argc; i++) {
args[i + 2] = argv[i];
}

return rb_funcall2(rb_cEnumerator, rb_intern("new"), argc + 2, args);
}
}

0 comments on commit 2f8d170

Please sign in to comment.