Project

General

Profile

Feature #6198 ยป 0000-attr-with-visibility.patch

riskwa (riskwa anon), 03/25/2012 02:58 AM

View differences:

ruby-1.9.3-p125-mod/object.c 2012-03-24 20:32:05.000000000 +0900
/*
* call-seq:
* attr_reader(symbol, ...) -> nil
* attr(symbol, ...) -> nil
* attr_reader(symbol, ...) -> [method-symbol, ...]
* attr(symbol, ...) -> [method-symbol, ...]
*
* Creates instance variables and corresponding methods that return the
* value of each instance variable. Equivalent to calling
......
rb_mod_attr_reader(int argc, VALUE *argv, VALUE klass)
{
int i;
VALUE result = rb_ary_new();
for (i=0; i<argc; i++) {
rb_attr(klass, rb_to_id(argv[i]), TRUE, FALSE, TRUE);
rb_ary_push(result, ID2SYM(rb_to_id(argv[i])));
}
return Qnil;
return result;
}
VALUE
......
/*
* call-seq:
* attr_writer(symbol, ...) -> nil
* attr_writer(symbol, ...) -> [method-symbol, ...]
*
* Creates an accessor method to allow assignment to the attribute
* <i>aSymbol</i><code>.id2name</code>.
* returns accessor method names like [:x=, :y=, ...]
*/
static VALUE
rb_mod_attr_writer(int argc, VALUE *argv, VALUE klass)
{
int i;
VALUE result = rb_ary_new();
for (i=0; i<argc; i++) {
rb_attr(klass, rb_to_id(argv[i]), FALSE, TRUE, TRUE);
rb_ary_push(result, ID2SYM(rb_id_attrset(rb_to_id(argv[i]))));
}
return Qnil;
return result;
}
/*
* call-seq:
* attr_accessor(symbol, ...) -> nil
* attr_accessor(symbol, ...) -> [method-symbol, ...]
*
* Defines a named attribute for this module, where the name is
* <i>symbol.</i><code>id2name</code>, creating an instance variable
* (<code>@name</code>) and a corresponding access method to read it.
* Also creates a method called <code>name=</code> to set the attribute.
* returns both read/write method names like [:x, :x=, :y, :y=, ...]
*
* module Mod
* attr_accessor(:one, :two)
......
rb_mod_attr_accessor(int argc, VALUE *argv, VALUE klass)
{
int i;
VALUE result = rb_ary_new();
for (i=0; i<argc; i++) {
rb_attr(klass, rb_to_id(argv[i]), TRUE, TRUE, TRUE);
rb_ary_push(result, ID2SYM(rb_to_id(argv[i])));
rb_ary_push(result, ID2SYM(rb_id_attrset(rb_to_id(argv[i]))));
}
return Qnil;
return result;
}
/*
ruby-1.9.3-p125-mod/test/ruby/test_module.rb 2012-03-25 00:52:53.000000000 +0900
INPUT
assert_in_out_err([], src, ["NameError"], [])
end
def test_attr_return_value
c = Class.new
c.class_eval do
@@r1 = attr_reader :r1
@@w1 = attr_writer :w1
@@rw1 = attr_accessor :rw1
@@r2 = attr_reader :r2_1, :r2_2, :r2_3
@@w2 = attr_writer :w2_1, :w2_2, :w2_3
@@rw2 = attr_accessor :rw2_1, :rw2_2, :rw2_3
def self.get_r1; @@r1; end
def self.get_w1; @@w1; end
def self.get_rw1; @@rw1; end
def self.get_r2; @@r2; end
def self.get_w2; @@w2; end
def self.get_rw2; @@rw2; end
end
assert_equal(c.get_r1, [:r1])
assert_equal(c.get_w1, [:w1=])
assert_equal(c.get_rw1.sort, [:rw1,:rw1=].sort)
assert_equal(c.get_r2, [:r2_1, :r2_2, :r2_3])
assert_equal(c.get_w2, [:w2_1=, :w2_2=, :w2_3=])
assert_equal(c.get_rw2.sort, [:rw2_1,:rw2_1=,
:rw2_2,:rw2_2=,
:rw2_3,:rw2_3=].sort)
end
def test_visibility_array
c = Class.new
c.class_eval do
def foo; end
def pub0; end
def pub1; end
def pub2; end
def pub3; end
def pro0; end
def pro1; end
def pro2; end
def pro3; end
def pri0; end
def pri1; end
def pri2; end
def pri3; end
public :pub0, [:pub1, :pub2], :pub3
protected :pro0, [], [:pro1], [:pro2, :pro3]
private [:pri0, :pri1, :pri2, :pri3]
end
pub = [true, false, false]
pro = [false, true, false]
pri = [false, false, true]
check = {
:pub0 => pub, :pub1 => pub, :pub2 => pub, :pub3 => pub,
:pro0 => pro, :pro1 => pro, :pro2 => pro, :pro3 => pro,
:pri0 => pri, :pri1 => pri, :pri2 => pri, :pri3 => pri,
}
check.each do |symbol, (ispub, ispro, ispri)|
assert_equal(ispub, c.public_method_defined?(symbol))
assert_equal(ispro, c.protected_method_defined?(symbol))
assert_equal(ispri, c.private_method_defined?(symbol))
end
end
def test_attr_visibility
c = Class.new
c.class_eval do
public attr_reader :pub_r1
protected attr_reader :pro_r1, :pro_r2
private attr_reader :pri_r1
public attr_writer :pub_w1, :pub_w2
protected attr_writer :pro_w1
private attr_writer :pri_w1
public attr_accessor :pub_a1
protected attr_accessor :pro_a1
private attr_accessor :pri_a1, :pri_a2
end
pub = [true, false, false]
pro = [false, true, false]
pri = [false, false, true]
none = [false, false, false]
check = {
:pub_r1 => pub, :pub_r1= => none,
:pro_r1 => pro, :pro_r1= => none,
:pro_r2 => pro, :pro_r2= => none,
:pri_r1 => pri, :pri_r1= => none,
:pub_w1 => none, :pub_w1= => pub,
:pub_w2 => none, :pub_w2= => pub,
:pro_w1 => none, :pro_w1= => pro,
:pri_w1 => none, :pri_w1= => pri,
:pub_a1 => pub, :pub_a1= => pub,
:pro_a1 => pro, :pro_a1 => pro,
:pri_a1 => pri, :pri_a1 => pri,
:pri_a2 => pri, :pri_a2 => pri,
}
check.each do |symbol, (ispub, ispro, ispri)|
assert_equal(ispub, c.public_method_defined?(symbol))
assert_equal(ispro, c.protected_method_defined?(symbol))
assert_equal(ispri, c.private_method_defined?(symbol))
end
end
end
ruby-1.9.3-p125-mod/vm_method.c 2012-03-25 01:24:47.000000000 +0900
}
}
static int
try_set_methods_visibilities(VALUE self, VALUE ary, rb_method_flag_t ex)
{
int i;
VALUE tmp = ary;
if(TYPE(ary) != T_ARRAY) {
tmp = rb_check_array_type(tmp);
if(NIL_P(tmp)) {
return FALSE;
}
}
for(i=0; i<RARRAY_LEN(ary); ++i) {
rb_export_method(self, rb_to_id(RARRAY_PTR(ary)[i]), ex);
}
return TRUE;
}
static void
set_method_visibility(VALUE self, int argc, VALUE *argv, rb_method_flag_t ex)
{
......
}
for (i = 0; i < argc; i++) {
rb_export_method(self, rb_to_id(argv[i]), ex);
if(!try_set_methods_visibilities(self, argv[i], ex)) {
rb_export_method(self, rb_to_id(argv[i]), ex);
}
}
rb_clear_cache_by_class(self);
}
......
* call-seq:
* public -> self
* public(symbol, ...) -> self
* public(array, ...) -> self
*
* With no arguments, sets the default visibility for subsequently
* defined methods to public. With arguments, sets the named methods to
* have public visibility.
* have public visibility. Arguments can contain array of symbols.
*/
static VALUE
......
* call-seq:
* protected -> self
* protected(symbol, ...) -> self
* protected(array, ...) -> self
*
* With no arguments, sets the default visibility for subsequently
* defined methods to protected. With arguments, sets the named methods
* to have protected visibility.
* to have protected visibility. Arguments can contain array of symbols.
*/
static VALUE
......
* call-seq:
* private -> self
* private(symbol, ...) -> self
* private(array, ...) -> self
*
* With no arguments, sets the default visibility for subsequently
* defined methods to private. With arguments, sets the named methods
* to have private visibility.
* to have private visibility. Arguments can contain array of symbols.
*
* module Mod
* def a() end
    (1-1/1)