Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rubinius/rubinius
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: e2d14371bd2d
Choose a base ref
...
head repository: rubinius/rubinius
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 6e9bf802e161
Choose a head ref
  • 3 commits
  • 6 files changed
  • 1 contributor

Commits on Feb 9, 2016

  1. Copy the full SHA
    61127a5 View commit details
  2. 2
    Copy the full SHA
    ca3bfcd View commit details
  3. Copy the full SHA
    6e9bf80 View commit details
38 changes: 38 additions & 0 deletions spec/ruby/optional/capi/class_spec.rb
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
load_extension("class")

autoload :ClassUnderAutoload, "#{extension_path}/class_under_autoload_spec"
autoload :ClassIdUnderAutoload, "#{extension_path}/class_id_under_autoload_spec"

describe :rb_path_to_class, :shared => true do
it "returns a class or module from a scoped String" do
@@ -214,6 +215,43 @@

ClassUnderAutoload.name.should == "ClassUnderAutoload"
end

it "raises a TypeError if class is defined and its superclass mismatches the given one" do
lambda { @s.rb_define_class_under(CApiClassSpecs, "Sub", nil) }.should raise_error(TypeError)
end
end

describe "rb_define_class_id_under" do
it "creates a subclass of the superclass contained in a module" do
cls = @s.rb_define_class_id_under(CApiClassSpecs, :ClassIdUnder1, CApiClassSpecs::Super)
cls.should be_kind_of(Class)
CApiClassSpecs::Super.should be_ancestor_of(CApiClassSpecs::ClassIdUnder1)
end

it "uses Object as the superclass if NULL is passed" do
@s.rb_define_class_id_under(CApiClassSpecs, :ClassIdUnder2, nil)
Object.should be_ancestor_of(CApiClassSpecs::ClassIdUnder2)
end

it "sets the class name" do
cls = @s.rb_define_class_id_under(CApiClassSpecs, :ClassIdUnder3, nil)
cls.name.should == "CApiClassSpecs::ClassIdUnder3"
end

it "calls #inherited on the superclass" do
CApiClassSpecs::Super.should_receive(:inherited)
@s.rb_define_class_id_under(CApiClassSpecs, :ClassIdUnder4, CApiClassSpecs::Super)
end

it "defines a class for an existing Autoload" do
compile_extension("class_id_under_autoload")

ClassIdUnderAutoload.name.should == "ClassIdUnderAutoload"
end

it "raises a TypeError if class is defined and its superclass mismatches the given one" do
lambda { @s.rb_define_class_id_under(CApiClassSpecs, :Sub, nil) }.should raise_error(TypeError)
end
end

describe "rb_define_class_variable" do
5 changes: 5 additions & 0 deletions spec/ruby/optional/capi/ext/class_id_under_autoload_spec.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "ruby.h"

void Init_class_id_under_autoload_spec(void) {
rb_define_class_id_under(rb_cObject, rb_intern("ClassIdUnderAutoload"), 0);
}
12 changes: 12 additions & 0 deletions spec/ruby/optional/capi/ext/class_spec.c
Original file line number Diff line number Diff line change
@@ -160,6 +160,14 @@ static VALUE class_spec_rb_define_class_under(VALUE self, VALUE outer,
}
#endif

#ifdef HAVE_RB_DEFINE_CLASS_ID_UNDER
static VALUE class_spec_rb_define_class_id_under(VALUE self, VALUE outer,
VALUE name, VALUE super) {
if(NIL_P(super)) super = 0;
return rb_define_class_id_under(outer, SYM2ID(name), super);
}
#endif

#ifdef HAVE_RB_DEFINE_CLASS_VARIABLE
static VALUE class_spec_define_class_variable(VALUE self, VALUE klass, VALUE name, VALUE val) {
rb_define_class_variable(klass, StringValuePtr(name), val);
@@ -250,6 +258,10 @@ void Init_class_spec() {
rb_define_method(cls, "rb_define_class_under", class_spec_rb_define_class_under, 3);
#endif

#ifdef HAVE_RB_DEFINE_CLASS_ID_UNDER
rb_define_method(cls, "rb_define_class_id_under", class_spec_rb_define_class_id_under, 3);
#endif

#ifdef HAVE_RB_DEFINE_CLASS_VARIABLE
rb_define_method(cls, "rb_define_class_variable", class_spec_define_class_variable, 3);
#endif
1 change: 1 addition & 0 deletions spec/ruby/optional/capi/ext/rubyspec.h
Original file line number Diff line number Diff line change
@@ -423,6 +423,7 @@
#define HAVE_RB_CONST_SET 1
#define HAVE_RB_DEFINE_ALIAS 1
#define HAVE_RB_DEFINE_CLASS_UNDER 1
#define HAVE_RB_DEFINE_CLASS_ID_UNDER 1
#define HAVE_RB_DEFINE_CONST 1
#define HAVE_RB_DEFINE_GLOBAL_CONST 1
#define HAVE_RB_DEFINE_GLOBAL_FUNCTION 1
10 changes: 6 additions & 4 deletions vm/capi/class.cpp
Original file line number Diff line number Diff line change
@@ -172,14 +172,12 @@ extern "C" {
}

/** @note Shares code with rb_define_module_under, change there too. --rue */
VALUE rb_define_class_under(VALUE outer, const char* name, VALUE super) {


VALUE rb_define_class_id_under(VALUE outer, ID name, VALUE super) {
NativeMethodEnvironment* env = NativeMethodEnvironment::get();

Module* module = c_as<Module>(env->get_object(outer));
Class* superclass = c_as<Class>(env->get_object(super ? super : rb_cObject));
Symbol* constant = env->state()->symbol(name);
Symbol* constant = reinterpret_cast<Symbol*>(name);

bool created = false;

@@ -212,6 +210,10 @@ extern "C" {
return klass;
}

VALUE rb_define_class_under(VALUE outer, const char* name, VALUE super) {
return rb_define_class_id_under(outer, rb_intern(name), super);
}

void rb_attr(VALUE klass, ID id, int read, int write, int ex) {
// TODO don't ignore ex.
if(read) {
3 changes: 3 additions & 0 deletions vm/include/capi/ruby/ruby.h
Original file line number Diff line number Diff line change
@@ -1300,6 +1300,9 @@ struct RTypedData {
/** Reopen or create new class with superclass and name under parent module. Returns the Class object. */
VALUE rb_define_class_under(VALUE parent, const char* name, VALUE superclass);

/** Reopen or create new class with superclass and name under parent module. Returns the Class object. */
VALUE rb_define_class_id_under(VALUE parent, ID name, VALUE superclass);

/** Define a toplevel constant */
void rb_define_global_const(const char* name, VALUE obj);