0000-attr-with-visibility.patch

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

Download (8.32 KB)

View differences:

ruby-1.9.3-p125-mod/object.c 2012-03-24 20:32:05.000000000 +0900
1683 1683

  
1684 1684
/*
1685 1685
 *  call-seq:
1686
 *     attr_reader(symbol, ...)    -> nil
1687
 *     attr(symbol, ...)             -> nil
1686
 *     attr_reader(symbol, ...)    -> [method-symbol, ...]
1687
 *     attr(symbol, ...)             -> [method-symbol, ...]
1688 1688
 *
1689 1689
 *  Creates instance variables and corresponding methods that return the
1690 1690
 *  value of each instance variable. Equivalent to calling
......
1695 1695
rb_mod_attr_reader(int argc, VALUE *argv, VALUE klass)
1696 1696
{
1697 1697
    int i;
1698
    VALUE result = rb_ary_new();
1698 1699

  
1699 1700
    for (i=0; i<argc; i++) {
1700 1701
	rb_attr(klass, rb_to_id(argv[i]), TRUE, FALSE, TRUE);
1702
	rb_ary_push(result, ID2SYM(rb_to_id(argv[i])));
1701 1703
    }
1702
    return Qnil;
1704

  
1705
    return result;
1703 1706
}
1704 1707

  
1705 1708
VALUE
......
1715 1718

  
1716 1719
/*
1717 1720
 *  call-seq:
1718
 *      attr_writer(symbol, ...)    -> nil
1721
 *      attr_writer(symbol, ...)    -> [method-symbol, ...]
1719 1722
 *
1720 1723
 *  Creates an accessor method to allow assignment to the attribute
1721 1724
 *  <i>aSymbol</i><code>.id2name</code>.
1725
 *  returns accessor method names like [:x=, :y=, ...]
1722 1726
 */
1723 1727

  
1724 1728
static VALUE
1725 1729
rb_mod_attr_writer(int argc, VALUE *argv, VALUE klass)
1726 1730
{
1727 1731
    int i;
1732
    VALUE result = rb_ary_new();
1728 1733

  
1729 1734
    for (i=0; i<argc; i++) {
1730 1735
	rb_attr(klass, rb_to_id(argv[i]), FALSE, TRUE, TRUE);
1736
	rb_ary_push(result, ID2SYM(rb_id_attrset(rb_to_id(argv[i]))));
1731 1737
    }
1732
    return Qnil;
1738

  
1739
    return result;
1733 1740
}
1734 1741

  
1735 1742
/*
1736 1743
 *  call-seq:
1737
 *     attr_accessor(symbol, ...)    -> nil
1744
 *     attr_accessor(symbol, ...)    -> [method-symbol, ...]
1738 1745
 *
1739 1746
 *  Defines a named attribute for this module, where the name is
1740 1747
 *  <i>symbol.</i><code>id2name</code>, creating an instance variable
1741 1748
 *  (<code>@name</code>) and a corresponding access method to read it.
1742 1749
 *  Also creates a method called <code>name=</code> to set the attribute.
1750
 *  returns both read/write method names like [:x, :x=, :y, :y=, ...]
1743 1751
 *
1744 1752
 *     module Mod
1745 1753
 *       attr_accessor(:one, :two)
......
1751 1759
rb_mod_attr_accessor(int argc, VALUE *argv, VALUE klass)
1752 1760
{
1753 1761
    int i;
1762
    VALUE result = rb_ary_new();
1754 1763

  
1755 1764
    for (i=0; i<argc; i++) {
1756 1765
	rb_attr(klass, rb_to_id(argv[i]), TRUE, TRUE, TRUE);
1766
	rb_ary_push(result, ID2SYM(rb_to_id(argv[i])));
1767
	rb_ary_push(result, ID2SYM(rb_id_attrset(rb_to_id(argv[i]))));
1757 1768
    }
1758
    return Qnil;
1769
    
1770
    return result;
1759 1771
}
1760 1772

  
1761 1773
/*
ruby-1.9.3-p125-mod/test/ruby/test_module.rb 2012-03-25 00:52:53.000000000 +0900
1220 1220
    INPUT
1221 1221
    assert_in_out_err([], src, ["NameError"], [])
1222 1222
  end
1223

  
1224
  def test_attr_return_value
1225
    c = Class.new
1226
    c.class_eval do
1227
      @@r1 = attr_reader :r1
1228
      @@w1 = attr_writer :w1
1229
      @@rw1 = attr_accessor :rw1
1230

  
1231
      @@r2 = attr_reader :r2_1, :r2_2, :r2_3
1232
      @@w2 = attr_writer :w2_1, :w2_2, :w2_3
1233
      @@rw2 = attr_accessor :rw2_1, :rw2_2, :rw2_3
1234

  
1235
      def self.get_r1; @@r1; end
1236
      def self.get_w1; @@w1; end
1237
      def self.get_rw1; @@rw1; end
1238
      def self.get_r2; @@r2; end
1239
      def self.get_w2; @@w2; end
1240
      def self.get_rw2; @@rw2; end
1241
    end
1242

  
1243
    assert_equal(c.get_r1, [:r1])
1244
    assert_equal(c.get_w1, [:w1=])
1245
    assert_equal(c.get_rw1.sort, [:rw1,:rw1=].sort)
1246

  
1247
    assert_equal(c.get_r2, [:r2_1, :r2_2, :r2_3])
1248
    assert_equal(c.get_w2, [:w2_1=, :w2_2=, :w2_3=])
1249
    assert_equal(c.get_rw2.sort, [:rw2_1,:rw2_1=,
1250
                                  :rw2_2,:rw2_2=,
1251
                                  :rw2_3,:rw2_3=].sort)
1252
  end
1253

  
1254
  def test_visibility_array
1255
    c = Class.new
1256
    c.class_eval do
1257
      def foo; end
1258
      def pub0; end
1259
      def pub1; end
1260
      def pub2; end
1261
      def pub3; end
1262
      
1263
      def pro0; end
1264
      def pro1; end
1265
      def pro2; end
1266
      def pro3; end
1267
      
1268
      def pri0; end
1269
      def pri1; end
1270
      def pri2; end
1271
      def pri3; end
1272
      
1273
      public :pub0, [:pub1, :pub2], :pub3
1274
      protected :pro0, [], [:pro1], [:pro2, :pro3]
1275
      private [:pri0, :pri1, :pri2, :pri3]
1276
    end
1277

  
1278
    pub = [true, false, false]
1279
    pro = [false, true, false]
1280
    pri = [false, false, true]
1281
    check = {
1282
      :pub0 => pub, :pub1 => pub, :pub2 => pub, :pub3 => pub,
1283
      :pro0 => pro, :pro1 => pro, :pro2 => pro, :pro3 => pro,
1284
      :pri0 => pri, :pri1 => pri, :pri2 => pri, :pri3 => pri,
1285
    }
1286

  
1287
    check.each do |symbol, (ispub, ispro, ispri)|
1288
      assert_equal(ispub, c.public_method_defined?(symbol))
1289
      assert_equal(ispro, c.protected_method_defined?(symbol))
1290
      assert_equal(ispri, c.private_method_defined?(symbol))
1291
    end
1292
  end
1293

  
1294
  def test_attr_visibility
1295
    c = Class.new
1296
    c.class_eval do
1297
      public attr_reader :pub_r1
1298
      protected attr_reader :pro_r1, :pro_r2
1299
      private attr_reader :pri_r1
1300
      
1301
      public attr_writer :pub_w1, :pub_w2
1302
      protected attr_writer :pro_w1
1303
      private attr_writer :pri_w1
1304

  
1305
      public attr_accessor :pub_a1
1306
      protected attr_accessor :pro_a1
1307
      private attr_accessor :pri_a1, :pri_a2
1308
    end
1309

  
1310
    pub = [true, false, false]
1311
    pro = [false, true, false]
1312
    pri = [false, false, true]
1313
    none = [false, false, false]
1314
    check = {
1315
      :pub_r1 => pub, :pub_r1= => none,
1316
      :pro_r1 => pro, :pro_r1= => none,
1317
      :pro_r2 => pro, :pro_r2= => none,
1318
      :pri_r1 => pri, :pri_r1= => none,
1319

  
1320
      :pub_w1 => none, :pub_w1= => pub,
1321
      :pub_w2 => none, :pub_w2= => pub,
1322
      :pro_w1 => none, :pro_w1= => pro,
1323
      :pri_w1 => none, :pri_w1= => pri,
1324

  
1325
      :pub_a1 => pub, :pub_a1= => pub,
1326
      :pro_a1 => pro, :pro_a1 => pro,
1327
      :pri_a1 => pri, :pri_a1 => pri,
1328
      :pri_a2 => pri, :pri_a2 => pri,
1329
    }
1330
    
1331
    check.each do |symbol, (ispub, ispro, ispri)|
1332
      assert_equal(ispub, c.public_method_defined?(symbol))
1333
      assert_equal(ispro, c.protected_method_defined?(symbol))
1334
      assert_equal(ispri, c.private_method_defined?(symbol))
1335
    end
1336
  end
1223 1337
end
ruby-1.9.3-p125-mod/vm_method.c 2012-03-25 01:24:47.000000000 +0900
958 958
    }
959 959
}
960 960

  
961
static int
962
try_set_methods_visibilities(VALUE self, VALUE ary, rb_method_flag_t ex)
963
{
964
    int i;
965
    VALUE tmp = ary;
966

  
967
    if(TYPE(ary) != T_ARRAY) {
968
	tmp = rb_check_array_type(tmp);
969
	if(NIL_P(tmp)) {
970
	    return FALSE;
971
	}
972
    }
973
    for(i=0; i<RARRAY_LEN(ary); ++i) {
974
	rb_export_method(self, rb_to_id(RARRAY_PTR(ary)[i]), ex);
975
    }
976
  
977
    return TRUE;
978
}
979

  
961 980
static void
962 981
set_method_visibility(VALUE self, int argc, VALUE *argv, rb_method_flag_t ex)
963 982
{
......
969 988
    }
970 989

  
971 990
    for (i = 0; i < argc; i++) {
972
	rb_export_method(self, rb_to_id(argv[i]), ex);
991
	if(!try_set_methods_visibilities(self, argv[i], ex)) {
992
  	    rb_export_method(self, rb_to_id(argv[i]), ex);
993
	}
973 994
    }
974 995
    rb_clear_cache_by_class(self);
975 996
}
......
978 999
 *  call-seq:
979 1000
 *     public                 -> self
980 1001
 *     public(symbol, ...)    -> self
1002
 *     public(array, ...)     -> self
981 1003
 *
982 1004
 *  With no arguments, sets the default visibility for subsequently
983 1005
 *  defined methods to public. With arguments, sets the named methods to
984
 *  have public visibility.
1006
 *  have public visibility. Arguments can contain array of symbols.
985 1007
 */
986 1008

  
987 1009
static VALUE
......
1001 1023
 *  call-seq:
1002 1024
 *     protected                -> self
1003 1025
 *     protected(symbol, ...)   -> self
1026
 *     protected(array, ...)    -> self
1004 1027
 *
1005 1028
 *  With no arguments, sets the default visibility for subsequently
1006 1029
 *  defined methods to protected. With arguments, sets the named methods
1007
 *  to have protected visibility.
1030
 *  to have protected visibility. Arguments can contain array of symbols.
1008 1031
 */
1009 1032

  
1010 1033
static VALUE
......
1024 1047
 *  call-seq:
1025 1048
 *     private                 -> self
1026 1049
 *     private(symbol, ...)    -> self
1050
 *     private(array, ...)     -> self
1027 1051
 *
1028 1052
 *  With no arguments, sets the default visibility for subsequently
1029 1053
 *  defined methods to private. With arguments, sets the named methods
1030
 *  to have private visibility.
1054
 *  to have private visibility. Arguments can contain array of symbols.
1031 1055
 *
1032 1056
 *     module Mod
1033 1057
 *       def a()  end