[Feature #2366] private constant

Feature #2366: private constant
http://redmine.ruby-lang.org/issues/show/2366

e$B5/I<<Te(B: Yusuke E.
e$B%9%F!<%?%9e(B: Open, e$BM%@hEYe(B: Normal
e$BC4Ev<Te(B: Yukihiro M., e$B%+%F%4%je(B: core, Target version:
1.9.x

e$B1sF#$G$9!#e(B

e$B:#$Ne(B Ruby e$B$K$O!“%/%i%9$,8x3+e(B API
e$B$+$I$&$+$rEA$($k<jCJ$,%I%-%e%a%s%He(B
e$B$7$+$”$j$^$;$s!#$=$N$?$a!“e(BERB::Compiler
e$B$J$I!”%i%$%V%i%j$NCf$N8x3+e(B
e$B$G$J$$e(B (e$B$H;W$o$l$ke(B) inner class
e$B$r30$+$i<+M3$K;2>H$G$-$F$7$^$$$^$9!#e(B

e$B$3$l$rKI$0$?$a$K$O!"F?L>%/%i%9$rMQ$$$FDj5A$9$l$PBgJ,1#JC$G$-$^$9$,!“e(B
e$B5-=R$,AjEvHQ;($K$J$C$F$7$^$$$^$9!#$^$?!”$=$N$h$&$K$7$F$7$^$&$H!"e(B
e$B!VHs8x3+$H$$$&$N$O>5CN$N>e$G4:$($F;H$$$?$$!W$H$$$&MW5a$KEz$($K$/$/e(B
e$B$J$j$^$9!#e(B

e$B$=$3$G!"Dj?t$Ke(B public/private
e$B$NB0@-$r;XDj$G$-$k$h$&$K$9$k$N$O$I$&e(B
e$B$G$7$g$&$+!#e(B

module SomeMod
class PublicInnerCls
end

class PrivateInnerCls
end

# PrivateInnerCls e$B$re(B private e$B$K$9$ke(B
private_constant :PrivateInnerCls

end

public e$B$JDj?t$O=>Mh$I$*$j;2>H$G$-$ke(B

p SomeMod::PublicInnerCls #=> SomeMod::PublicInnerCls

private e$B$JDj?t$r30$+$i;2>H$7$h$&$H$9$k$HNc30e(B

p SomeMod::PrivateInnerCls #=> private constant (RuntimeError)

e$BF1$8%9%3!<%W$+$i$O;2>H$G$-$ke(B (e$BK>$`$J$i<+J,$NB-$r7b$F$ke(B)

p SomeMod.module_eval { PrivateInnerCls } #=>
SomeMod::PrivateInnerCls
p(module SomeMod; PrivateInnerCls; end) #=>
SomeMod::PrivateInnerCls

e$BMW$9$k$K!"%a%=%C%I$Ne(B public/private e$B$HF1$846$8$G$9!#e(B

e$B:Y$+$$;EMM$O5M$a$F$$$^$;$s$,!“e(Bproof of concept
e$B$N%Q%C%A$rIU$1$^$9!#e(B
1 e$BDj?t$4$H$Ke(B 2
e$BMWAG$NG[Ns$r:n$C$F$7$^$&$N$G!”$A$c$s$H$7$?<BAu$OI,MWe(B
e$B$@$H;W$$$^$9!#e(B

e$B$I$s$J$b$N$G$7$g$&$+!#e(B

e$B$A$J$_$K$3$NDs0F$N$-$C$+$1$Oe(B [ruby-dev:39677] e$B$G$9!#e(B

diff --git a/variable.c b/variable.c
index 779a8e8…db3a81c 100644
— a/variable.c
+++ b/variable.c
@@ -1525,6 +1525,33 @@ rb_autoload_p(VALUE mod, ID id)
return load && (file = load->nd_lit) ? file : Qnil;
}

+void
+rb_change_const_visibility(VALUE klass, ID id, VALUE ex)
+{

  • VALUE value, tmp;
  • int mod_retry = 0;
  • tmp = klass;
  • while (RTEST(tmp)) {
  • VALUE am = 0;
  • while (RCLASS_IV_TBL(tmp) && st_lookup(RCLASS_IV_TBL(tmp),
    (st_data_t)id, &value)) {
  •  if (value == Qundef) {
    
  • if (am == tmp) break;
  • am = tmp;
  • rb_autoload_load(tmp, id);
  • continue;
  •  }
    
  •  if (tmp == rb_cObject && klass != rb_cObject) {
    
  • rb_warn(“toplevel constant %s referenced by %s::%s”,
  •  rb_id2name(id), rb_class2name(klass), rb_id2name(id));
    
  •  }
    
  •  RARRAY_PTR(value)[1] = ex;
    
  •  return;
    
  • }
  • tmp = RCLASS_SUPER(tmp);
  • }
    +}

static VALUE
rb_const_get_0(VALUE klass, ID id, int exclude, int recurse)
{
@@ -1546,7 +1573,10 @@ rb_const_get_0(VALUE klass, ID id, int exclude,
int recurse)
rb_warn(“toplevel constant %s referenced by %s::%s”,
rb_id2name(id), rb_class2name(klass), rb_id2name(id));
}

  •  return value;
    
  •  if (!RARRAY_PTR(value)[1]) {
    
  • rb_raise(rb_eRuntimeError, “private constant”);
  •  }
    
  •  return RARRAY_PTR(value)[0];
    
    }
    if (!recurse && klass != rb_cObject) break;
    tmp = RCLASS_SUPER(tmp);
    @@ -1798,11 +1828,13 @@ mod_av_set(VALUE klass, ID id, VALUE val, int
    isconst)
    void
    rb_const_set(VALUE klass, ID id, VALUE val)
    {
  • VALUE ary;
    if (NIL_P(klass)) {
    rb_raise(rb_eTypeError, “no class/module to define constant %s”,
    rb_id2name(id));
    }
  • mod_av_set(klass, id, val, TRUE);
  • ary = rb_ary_new3(2, val, Qtrue);
  • mod_av_set(klass, id, ary, TRUE);
    }

void
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 0660c7d…e3e789e 100644
— a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1141,7 +1141,7 @@ vm_get_ev_const(rb_thread_t *th, const rb_iseq_t
*iseq,
return 1;
}
else {

  •      return val;
    
  •      return RARRAY_PTR(val)[0];
     }
       }
    
    }
    diff --git a/vm_method.c b/vm_method.c
    index 557583f…40b125a 100644
    — a/vm_method.c
    +++ b/vm_method.c
    @@ -1038,6 +1038,30 @@ rb_mod_private_method(int argc, VALUE *argv,
    VALUE obj)
    return obj;
    }

+static void
+set_const_visibility(VALUE self, int argc, VALUE *argv, VALUE ex)
+{

  • int i;
  • extern void rb_change_const_visibility(VALUE klass, ID id, VALUE
    ex);
  • secure_visibility(self);
  • for (i = 0; i < argc; i++) {
  • rb_change_const_visibility(self, rb_to_id(argv[i]), ex);
  • }
  • rb_clear_cache_by_class(self);
    +}

+static VALUE
+rb_mod_public_constant(int argc, VALUE *argv, VALUE obj)
+{

  • set_const_visibility(obj, argc, argv, Qtrue);
    +}

+static VALUE
+rb_mod_private_constant(int argc, VALUE *argv, VALUE obj)
+{

  • set_const_visibility(obj, argc, argv, Qfalse);
    +}

/*

  • call-seq:
  • public
    

@@ -1250,6 +1274,8 @@ Init_eval_method(void)
rb_define_method(rb_cModule, “protected_method_defined?”,
rb_mod_protected_method_defined, 1);
rb_define_method(rb_cModule, “public_class_method”,
rb_mod_public_method, -1);
rb_define_method(rb_cModule, “private_class_method”,
rb_mod_private_method, -1);

  • rb_define_method(rb_cModule, “public_constant”,
    rb_mod_public_constant, -1);

  • rb_define_method(rb_cModule, “private_constant”,
    rb_mod_private_constant, -1);

    rb_define_singleton_method(rb_vm_top_self(), “public”, top_public,
    -1);
    rb_define_singleton_method(rb_vm_top_self(), “private”,
    top_private, -1);


Yusuke E. [email protected]

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:39685] [Feature #2366] private constant”
on Sat, 14 Nov 2009 14:30:32 +0900, Yusuke E.
[email protected] writes:

|e$B:#$Ne(B Ruby e$B$K$O!“%/%i%9$,8x3+e(B API e$B$+$I$&$+$rEA$($k<jCJ$,%I%-%e%a%s%He(B
|e$B$7$+$”$j$^$;$s!#$=$N$?$a!“e(BERB::Compiler e$B$J$I!”%i%$%V%i%j$NCf$N8x3+e(B
|e$B$G$J$$e(B (e$B$H;W$o$l$ke(B) inner class e$B$r30$+$i<+M3$K;2>H$G$-$F$7$^$$$^$9!#e(B
|
|e$B$3$l$rKI$0$?$a$K$O!"F?L>%/%i%9$rMQ$$$FDj5A$9$l$PBgJ,1#JC$G$-$^$9$,!“e(B
|e$B5-=R$,AjEvHQ;($K$J$C$F$7$^$$$^$9!#$^$?!”$=$N$h$&$K$7$F$7$^$&$H!"e(B
|e$B!VHs8x3+$H$$$&$N$O>5CN$N>e$G4:$($F;H$$$?$$!W$H$$$&MW5a$KEz$($K$/$/e(B
|e$B$J$j$^$9!#e(B
|
|e$B$=$3$G!"Dj?t$Ke(B public/private e$B$NB0@-$r;XDj$G$-$k$h$&$K$9$k$N$O$I$&e(B
|e$B$G$7$g$&$+!#e(B

e$B$J$k$[$I!“NI$$%”%$%G%#%“$@$H;W$$$^$9!#:NMQ$9$k%?%$%%s%0$Oe(B
Yuguie$B$5$s$K?V$$$F$
$J$$$H$$$1$^$;$s$,!”$$$:$l:NMQ$7$?$$$H;W$$e(B
e$B$^$9!#e(BYuguie$B$5$s$O$I$&;W$$$^$9$+!)e(B

e$B1sF#$G$9!#e(B

e$B:#$Ne(B Ruby e$B$K$O!"%/%i%9$,8x3+e(B API e$B$+$I$&$+$rEA$($k<jCJ$,%I%-%e%a%s%He(B
e$B$7$+$"$j$^$;$s!#$=$N$?$a!“e(BERB::Compiler e$B$J$I!”%i%$%V%i%j$NCf$N8x3+e(B
e$B$G$J$$e(B (e$B$H;W$o$l$ke(B) inner class e$B$r30$+$i<+M3$K;2>H$G$-$F$7$^$$$^$9!#e(B

e$B$J$k$[$I!“NI$$%”%$%G%#%"$@$H;W$$$^$9!#:NMQ$9$k%?%$%%s%0$Oe(B
Yuguie$B$5$s$K?V$$$F$
$J$$$H$$$1$^$;$s$,!"$$$:$l:NMQ$7$?$$$H;W$$e(B
e$B$^$9!#e(BYuguie$B$5$s$O$I$&;W$$$^$9$+!)e(B

e$B$7$+$7!"$3$3$^$G=q$$$F$+$i5$$,$D$-$^$7$?$,!"$b$7e(B rb_classext_t e$B$de(B
RCLASS_IV_TBL e$B$,8x3+e(B API e$B$@$C$?$i!"$3$N%Q%C%A$O%P%$%J%j8_49@-$re(B
e$B2u$9$3$H$K$J$j$=$&$G$9!#4X?t%l%Y%k$G$N8_49@-$OJQ$o$i$J$$e(B (e$B$O$:e(B)
e$B$G$9$,!#e(B

Yugui e$B$5$s$NJV;v$O%a!<%k$G$OMh$F$$$^$;$s$,!"e(BIRC e$B$Ge(B

  • 1.9.2 e$B$G$Oe(B rb_classext_t e$B$NDj5A$Ke(B /** internal */
    e$B$HIU$1$ke(B (e$B=hCV:Q$_e(B)
  • 1.9.3 e$B0J9_$G$3$NJQ99$rF~$l$ke(B

e$B$H$$$&H=CG$r$b$i$C$F$$$^$9!#e(B

e$B$G$9$,!":G6ae(B rubyspec
e$B$KL$rDL$7$F$$$F!"$3$N5!G=$OAa$/F~$l$?J}$,$$$$$He(B
e$B;W$$$^$7$?!#e(B

rubyspec e$B$G$O!Ve(Bprivate method e$B$O4pK\E*$Ke(B spec
e$B$K=q$+$J$$e(B (#initialize
e$B$J$I0lItNc30$O$"$ke(B)e$B!W$H$$$&e(B convension
e$B$,$"$j$D$D$b!“e(B:nodoc: e$B$NIU$$$?e(B
CGI::Html3 e$B$_$?$$$J%/%i%9$Ne(B spec e$B$r=q$$$F$$$F!”$=$N$;$$$Ge(B
1.9 e$B$G%(%i!<e(B
e$B$,BgNL$KH/@8$9$k$h$&$K$J$C$F$$$^$9!#e(B
e$B$3$l$O!“e(Bprivate constant
e$B$5$($”$l$PH/@8$7$J$+$C$?IT9,$@$H;W$$$^$9!#e(B

e$B=>$C$F!“Hs8x3+%/%i%9$G$”$k$3$H$rL@<($9$ke(B private constant
e$B$rF~$l$k;v$Oe(B
e$B$o$j$H5^L3$G$O$J$$$+$H;W$$$^$9!#$5$i$K!“e(Brubyspec
e$B$r%Q%9$9$k$3$H$rI8\Ve(B
e$B$7$F$$$ke(B ruby 1.9.2
e$B$N%j%j!<%9$rAa$a$k$3$H$K7R$,$k$s$8$c$J$$$+$J$”$H$be(B
e$B4|BT$7$F$$$^$9!#e(B
e$BHs8_49$K$D$$$F$O!"L5;k$G$-$k%l%Y%k$@$H;W$$$^$9!#e(B

e$B$H$$$&$o$1$G!"e(BYugui e$B$5$s$I$&$G$7$g$&$+!#e(B

e$B31$H$$$$$^$9!#e(B

On 2010/01/28, at 20:55, Yusuke ENDOH wrote:

RCLASS_IV_TBL e$B$,8x3+e(B API e$B$@$C$?$i!"$3$N%Q%C%A$O%P%$%J%j8_49@-$re(B

e$B=>$C$F!“Hs8x3+%/%i%9$G$”$k$3$H$rL@<($9$ke(B private constant e$B$rF~$l$k;v$Oe(B
e$B$o$j$H5^L3$G$O$J$$$+$H;W$$$^$9!#$5$i$K!“e(Brubyspec e$B$r%Q%9$9$k$3$H$rI8\Ve(B
e$B$7$F$$$ke(B ruby 1.9.2 e$B$N%j%j!<%9$rAa$a$k$3$H$K7R$,$k$s$8$c$J$$$+$J$”$H$be(B
e$B4|BT$7$F$$$^$9!#e(B
e$BHs8_49$K$D$$$F$O!"L5;k$G$-$k%l%Y%k$@$H;W$$$^$9!#e(B

e$B$H$$$&$o$1$G!"e(BYugui e$B$5$s$I$&$G$7$g$&$+!#e(B

e$B$9$_$^$;$s!#65$($F2<$5$$!#e(B

e$BHs8x3+%/%i%9$H$$$&$N$O!“e(Brubyspece$B$h!”%F%9%H%3!<%I$r=q$+$J$$$G!*$H$$$&e(B
e$B@k8@$r$9$k$b$N$G$9$+!)e(B

e$B$=$l$H$b!"%"%W%j%1!<%7%g%s$,;H$C$?$jF0E*$KDj5A$r$+$($F$O$$$1$^$;$s!"e(B
e$B$H$$$&@k8@$r$9$k$b$N$G$9$+!)e(B

e$B$?$H$($P!"e(BERB::Compilere$B$G$7$?$i!“e(Bspece$B$r=q$$$F$[$7$$$H$O;W$o$J$$$1$Ie(B
e$B%”%W%j%1!<%7%g%s$GDj5A$r=q$-49$($F!"e(BERBe$B$N5sF0$rJQ$($k$N$O;_$a$5$;$?$$e(B
e$B$H$^$G$O;W$$$^$;$s!#e(B

e$B$b$7e(BERBe$B$N<BAu$,JQ$o$C$F$7$^$C$F$=$N=q$-49$($r$9$k%3!<%I$,F0$+$J$/$J$C$Fe(B
e$B$7$^$&$N$O!";EMM$,JQ$o$C$?!"$HG<F@$7$F$b$i$C$F$bNI$$$h$&$J5$$,$7$^$9!#e(B

e$B1sF#$G$9!#e(B

2010e$BG/e(B1e$B7ne(B29e$BF|e(B20:30 Masatoshi SEKI
[email protected]:

e$B$=$l$H$b!“%”%W%j%1!<%7%g%s$,;H$C$?$jF0E*$KDj5A$r$+$($F$O$$$1$^$;$s!"e(B
e$B$H$$$&@k8@$r$9$k$b$N$G$9$+!)e(B

e$BN>J}$N$D$b$j$G$9!#e(B

e$B$?$H$($P!"e(BERB::Compilere$B$G$7$?$i!“e(Bspece$B$r=q$$$F$[$7$$$H$O;W$o$J$$$1$Ie(B
e$B%”%W%j%1!<%7%g%s$GDj5A$r=q$-49$($F!"e(BERBe$B$N5sF0$rJQ$($k$N$O;_$a$5$;$?$$e(B
e$B$H$^$G$O;W$$$^$;$s!#e(B

e$B85$NDs0Fe(B [ruby-dev:39685]
e$B$K=q$-$^$7$?$,!“!VHs8x3+$H$$$&$N$O>5CN$N>e$Ge(B
e$B4:$($F;H$$$?$$!W$H$$$&MW5a$rIu$8$k$b$N$G$O$”$j$^$;$s!#;H$&$N$K0l<j4Ve(B
e$B$+$+$k$h$&$K$J$k$@$1$G$9!#0l<j4V$+$1$k$3$H$G!"<+J,$,<+J,$NB-$r7b$H$&$He(B
e$B$7$F$$$k$3$H$r<+3P$7$F$b$i$*$&$H$$$&A@$$$G$9!#e(B

e$B$b$7e(BERBe$B$N<BAu$,JQ$o$C$F$7$^$C$F$=$N=q$-49$($r$9$k%3!<%I$,F0$+$J$/$J$C$Fe(B
e$B$7$^$&$N$O!“;EMM$,JQ$o$C$?!”$HG<F@$7$F$b$i$C$F$bNI$$$h$&$J5$$,$7$^$9!#e(B

e$BG<F@$7$F$/$l$k?M$O$$$$$s$G$9$1$I$M!#e(Brubyspec
e$B$NMM;R$r8+$k$H!"$=$&$$$&e(B
e$BKR2NE*$J4|BT$OFq$7$$5$$,$7$F$$$^$9!#e(B

e$BIaDL$K8+$($k$b$N$O2?$G$be(B spec
e$B$K$5$l$F$7$^$&Nc$H$7$F!“0J2<$N$h$&$Je(B spec
e$B$,$”$j$^$9!#e(B(private constant e$B$K$O4X78$J$$$G$9$,!D!De(B)

http://github.com/rubyspec/rubyspec/blob/master/library/erb/src_spec.rb

e$B$D$^$j!“e(BERB#src e$B$NJV$jCM$r8GDjJ8;zNs$Ge(B spec
e$B$K$7$F$$$k$H$$$&!#e(B1.9 e$B$G<:GTe(B
e$B$7$F$k$s$G$9$,!”$I$&BP=h$7$?$b$N$G$7$g$&!#e(B

e$B%A%1%C%He(B #2366 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B%U%!%$%ke(B const_tbl.patch e$BDI2Ce(B
e$B%U%!%$%ke(B const_entry.patch e$BDI2Ce(B
e$B%U%!%$%ke(B private_constant.patch e$BDI2Ce(B

e$B1sF#$G$9!#e(B

e$B$J$k$[$I!“NI$$%”%$%G%#%“$@$H;W$$$^$9!#:NMQ$9$k%?%$%%s%0$Oe(B
Yuguie$B$5$s$K?V$$$F$
$J$$$H$$$1$^$;$s$,!”$$$:$l:NMQ$7$?$$$H;W$$e(B
e$B$^$9!#e(B

e$B$"$j$,$H$&$4$6$$$^$9!#e(B

e$B$5$5$@$5$s$HOC$7$F!"$b$&$A$g$C$H$A$c$s$H$7$?<BAu$r:n$j$^$7$?!#e(B
e$B7k9=5pBg$JJQ99$K$J$C$?$N$G!"e(B3 e$BCJ3,$N%Q%C%A$KJ,$1$^$7$?!#e(B

  1. const_tbl.patch:
    e$B%/%i%9$N;}$DDj?t$d%/%i%9JQ?t$d$=$NB>$r$4$A$c$^$<$K4IM}$7$F$$$ke(B
    RCLASS_IV_TBL e$B$+$i!"Dj?t$@$1$r4IM}$9$ke(B RCLASS_CONST_TBL
    e$B$r@Z$je(B
    e$B=P$9!#e(B

  2. const_entry.patch
    RCLASS_CONST_TBL e$B$N%(%s%H%j$,Dj?t$ND>@\CM$r;X$7$F$$$?$H$3$m$r!"e(B
    rb_const_entry_t e$B$r$O$5$s$G4V@\E*$K;X$9$h$&$K$9$k!#e(B
    rb_const_entry_t e$B$K$Oe(B visibility e$B$N%U%i%0$r;}$?$;$k!#e(B
    rb_const_entry_t e$B$Oe(B malloc e$B$G4IM}$5$l$k!#e(B

  3. private_constant.patch
    Module#public_constant e$B$He(B private_constant
    e$B$rDj5A$7!"e(Bprivate
    constant e$B$N;2>H$GNc30$rEj$2$k!#e(B

make test-all e$B$G%(%i!<$,A}$($k$3$H$O$J$$$h$&$G$9!#e(B

Yuguie$B$5$s$O$I$&;W$$$^$9$+!)e(B

e$B$I$&$G$7$g$&$+!#e(B

API e$B$rN}$kI,MW$,$"$j$=$&e(B (Module#constants
e$B$K0z?t;}$?$;$k$+$H$+e(B
Module#private_constants e$B$r:n$k$+$H$+e(B) e$B$J$N$G!"L5M}$Ke(B 1.9.2
e$B$Ke(B
e$BF~$l$J$/$F$b$$$$$H;W$$$^$9$,!“Dj?t%F!<%V%k$N@Z$j=P$7$,COL#$KBgJQe(B
e$B$@$C$?e(B (1 e$B$N%Q%C%Ae(B)
e$B$N$G!”$3$l$@$1F~$l$F$*$/$H8e$G3Z$=$&$G$9!#e(B

e$B$7$+$7!“$3$3$^$G=q$$$F$+$i5$$,$D$-$^$7$?$,!”$b$7e(B rb_classext_t
e$B$de(B
RCLASS_IV_TBL e$B$,8x3+e(B API
e$B$@$C$?$i!"$3$N%Q%C%A$O%P%$%J%j8_49@-$re(B
e$B2u$9$3$H$K$J$j$=$&$G$9!#4X?t%l%Y%k$G$N8_49@-$OJQ$o$i$J$$e(B
(e$B$O$:e(B)
e$B$G$9$,!#e(B


Yusuke E. [email protected]

http://redmine.ruby-lang.org/issues/show/2366

e$B31$H$$$$$^$9!#e(B

e$B<ALd$P$+$j$G?=$7Lu$"$j$^$;$s!#e(B

On 2010/01/29, at 23:21, Yusuke ENDOH wrote:

e$BHs8x3+%/%i%9$H$$$&$N$O!“e(Brubyspece$B$h!”%F%9%H%3!<%I$r=q$+$J$$$G!*$H$$$&e(B
e$B$H$^$G$O;W$$$^$;$s!#e(B

e$B85$NDs0Fe(B [ruby-dev:39685] e$B$K=q$-$^$7$?$,!“!VHs8x3+$H$$$&$N$O>5CN$N>e$Ge(B
e$B4:$($F;H$$$?$$!W$H$$$&MW5a$rIu$8$k$b$N$G$O$”$j$^$;$s!#;H$&$N$K0l<j4Ve(B
e$B$+$+$k$h$&$K$J$k$@$1$G$9!#0l<j4V$+$1$k$3$H$G!"<+J,$,<+J,$NB-$r7b$H$&$He(B
e$B$7$F$$$k$3$H$r<+3P$7$F$b$i$*$&$H$$$&A@$$$G$9!#e(B

e$B$&!<$s!#$=$&$9$k$H$=$&@k8@$7$J$+$C$?$b$N$O!"$I$&$J$k$s$G$7$g$&!#e(B

e$B!VJQ$($J$$$C$F8@$C$?$N$KJQ99$7$d$,$C$F!*!W$HE$i$l$k$H$+!)e(B

e$B$b$7e(BERBe$B$N<BAu$,JQ$o$C$F$7$^$C$F$=$N=q$-49$($r$9$k%3!<%I$,F0$+$J$/$J$C$Fe(B
e$B$7$^$&$N$O!“;EMM$,JQ$o$C$?!”$HG<F@$7$F$b$i$C$F$bNI$$$h$&$J5$$,$7$^$9!#e(B

e$BG<F@$7$F$/$l$k?M$O$$$$$s$G$9$1$I$M!#e(Brubyspec e$B$NMM;R$r8+$k$H!"$=$&$$$&e(B
e$BKR2NE*$J4|BT$OFq$7$$5$$,$7$F$$$^$9!#e(B

e$B$($H!“e(Brubyspece$B$H$$$&$N$O$=$&$$$&JQ2=$r$_$D$1$F$/$l$k%;%s%5!<$N$h$&$Je(B
e$B$b$N$G$O$J$/!”$J$K$+$r5,Dj$9$k$b$N$J$s$G$7$g$&$+!#e(B

e$B%F%9%H$K$h$C$FJQ2=$r8+$D$1$?$i!"JQ99$7$?$H@k8@$9$l$P$h$$$N$G$O$J$$$Ne(B
e$B$G$9$+!)e(B

rubyspece$B$K=q$+$l$?$b$N$O!"=$@5$9$k$3$H$,$G$-$J$/$J$k$H$$$&$3$H$G$7$g$&$+!)e(B

e$BIaDL$K8+$($k$b$N$O2?$G$be(B spec e$B$K$5$l$F$7$^$&Nc$H$7$F!“0J2<$N$h$&$Je(B spec
e$B$,$”$j$^$9!#e(B(private constant e$B$K$O4X78$J$$$G$9$,!D!De(B)

http://github.com/rubyspec/rubyspec/blob/master/library/erb/src_spec.rb

e$B$D$^$j!“e(BERB#src e$B$NJV$jCM$r8GDjJ8;zNs$Ge(B spec e$B$K$7$F$$$k$H$$$&!#e(B1.9 e$B$G<:GTe(B
e$B$7$F$k$s$G$9$,!”$I$&BP=h$7$?$b$N$G$7$g$&!#e(B

e$B$=$N%;%s%9$,$$$$$+$I$&$+$O$*$$$H$$$F!Ee(B

ERB#srce$B$N7k2L$NJ8;zNs$K6=L#$,$"$k?M$K$H$C$F$O!“0c$&$b$N$rJV$7$F$k$Ne(B
e$B$@$+$i!”;EMMJQ99$7$d$,$C$?$s$G$9$h$M!#e(B

e$B$“$k%P!<%8%g%s$Ne(BERB#srce$B$H$^$?JL$N%P!<%8%g%s$Ne(BERB#srce$B$N5sF0$O0c$&$N$Ge(B
e$B$”$l$P!“A4$F$N%P%j%(!<%7%g%s$K$D$$$F4|BT$9$k7k2L$r=q$+$;$F$”$2$F$be(B
e$B$h$$$N$G$O$J$$$G$9$+$M$(!#e(B

e$B@.@%$G$9!#e(B

(2010/01/30 3:57), Masatoshi SEKI wrote:

e$B85$NDs0Fe(B [ruby-dev:39685] e$B$K=q$-$^$7$?$,!“!VHs8x3+$H$$$&$N$O>5CN$N>e$Ge(B
e$B4:$($F;H$$$?$$!W$H$$$&MW5a$rIu$8$k$b$N$G$O$”$j$^$;$s!#;H$&$N$K0l<j4Ve(B
e$B$+$+$k$h$&$K$J$k$@$1$G$9!#0l<j4V$+$1$k$3$H$G!"<+J,$,<+J,$NB-$r7b$H$&$He(B
e$B$7$F$$$k$3$H$r<+3P$7$F$b$i$*$&$H$$$&A@$$$G$9!#e(B

e$B$&!<$s!#$=$&$9$k$H$=$&@k8@$7$J$+$C$?$b$N$O!"$I$&$J$k$s$G$7$g$&!#e(B

e$B!VJQ$($J$$$C$F8@$C$?$N$KJQ99$7$d$,$C$F!*!W$HE$i$l$k$H$+!)e(B

e$B!VJQ$($J$$!W$H8@$C$?3P$($O$J$$$o$1$G$9$,!“e(B
e$B8x3+e(BAPIe$B$G$”$k0J>e0B0W$J;EMMJQ99$O?5$`;v$,4|BT$5$l$^$9!#e(B
e$B$=$b$=$b!“e(BRails e$B0J9_e(B Ruby
e$B$G$b;EMMJQ99$O95$($k$3$H$,4|BT$5$l$D$D$”$j$^$9!#e(B

e$B$b$7e(BERBe$B$N<BAu$,JQ$o$C$F$7$^$C$F$=$N=q$-49$($r$9$k%3!<%I$,F0$+$J$/$J$C$Fe(B
e$B$7$^$&$N$O!“;EMM$,JQ$o$C$?!”$HG<F@$7$F$b$i$C$F$bNI$$$h$&$J5$$,$7$^$9!#e(B

e$BG<F@$7$F$/$l$k?M$O$$$$$s$G$9$1$I$M!#e(Brubyspec e$B$NMM;R$r8+$k$H!"$=$&$$$&e(B
e$BKR2NE*$J4|BT$OFq$7$$5$$,$7$F$$$^$9!#e(B

e$B$($H!“e(Brubyspece$B$H$$$&$N$O$=$&$$$&JQ2=$r$_$D$1$F$/$l$k%;%s%5!<$N$h$&$Je(B
e$B$b$N$G$O$J$/!”$J$K$+$r5,Dj$9$k$b$N$J$s$G$7$g$&$+!#e(B

“spec” e$B$G$9$7!#e(B
e$B$=$b$=$b!"e(BRubySpec e$B$OC/$N$?$a$N$b$N$+$C$F!“e(BMRI
e$B$N$?$a$8$c$J$$$s$G$9$h!#e(B
JRuby e$B$de(B Rubiniuse$B!“e(BMacRubye$B!”$”$He(B IronRuby
e$B$N$?$a$N$b$N$G$9!#e(B
e$BH`$i$,<BAu$9$Y$-!Ve(BRubye$B!W$N8@8l;EMM$r5,Dj$9$k$N$,e(B RubySpec
e$B$G$9!#e(B

e$B%F%9%H$K$h$C$FJQ2=$r8+$D$1$?$i!"JQ99$7$?$H@k8@$9$l$P$h$$$N$G$O$J$$$Ne(B
e$B$G$9$+!)e(B

rubyspece$B$K=q$+$l$?$b$N$O!"=$@5$9$k$3$H$,$G$-$J$/$J$k$H$$$&$3$H$G$7$g$&$+!)e(B

RubySpec e$B$K=q$+$l$?$b$N!=!=$H$$$&$+!"=q$+$l$&$kJ*$O8x3+e(B API
e$B$G$9$N$G!“e(B
e$B$=$l$r=$@5$9$k;v$O;EMMJQ99!”$R$$$F$O!Ve(BRubye$B!W8@8l;EMM$NJQ99$r0UL#$7!"e(B
Ruby e$B8_49<BAu$r:n$C$F$$$k?M!9A4$F$KDI=>$rMW5a$9$k$3$H$K$J$j$^$9!#e(B
e$B$?$H$(C/$b;H$C$F$$$J$$e(B API e$B$G$b!#e(B

e$B$=$l$G$b;EMMJQ99$G$"$k$H@k8@$9$k$J$i$P$b$A$m$sJQ99$O2DG=$G$9!#e(B

e$BIaDL$K8+$($k$b$N$O2?$G$be(B spec e$B$K$5$l$F$7$^$&Nc$H$7$F!“0J2<$N$h$&$Je(B spec
e$B$,$”$j$^$9!#e(B(private constant e$B$K$O4X78$J$$$G$9$,!D!De(B)

http://github.com/rubyspec/rubyspec/blob/master/library/erb/src_spec.rb

e$B$D$^$j!“e(BERB#src e$B$NJV$jCM$r8GDjJ8;zNs$Ge(B spec e$B$K$7$F$$$k$H$$$&!#e(B1.9 e$B$G<:GTe(B
e$B$7$F$k$s$G$9$,!”$I$&BP=h$7$?$b$N$G$7$g$&!#e(B

e$B$=$N%;%s%9$,$$$$$+$I$&$+$O$*$$$H$$$F!Ee(B

e$B%;%s%9$NLdBj$8$c$J$$$s$G$9$h!#e(B
RubySpec e$B$N:n$j<jC#$K$C$F!"H`$i$N%f!<%6$O0-L>9b$-e(B Rails
e$B$J$o$1$G!"e(B
ERB#src e$B$@$m$&$,$J$s$@$m$&$,MF<O$J$/;H$C$F$-$^$9!#e(B
e$B$G$9$+$i!"8x3+e(B API e$B$J$i$P%F%9%H$9$k$N$OEvA3$G$9!#e(B

ERB#srce$B$N7k2L$NJ8;zNs$K6=L#$,$"$k?M$K$H$C$F$O!“0c$&$b$N$rJV$7$F$k$Ne(B
e$B$@$+$i!”;EMMJQ99$7$d$,$C$?$s$G$9$h$M!#e(B

MatzRuby
e$B$O;EMMJQ99$N>l9g%"%W%j%1!<%7%g%sB&$KDI=>$rMW5a$9$kJ82=$G$9$,!"e(B
e$B8=>u8_49<BAu$ON)>l$,<e$$$N$G!#e(B

e$B$“$k%P!<%8%g%s$Ne(BERB#srce$B$H$^$?JL$N%P!<%8%g%s$Ne(BERB#srce$B$N5sF0$O0c$&$N$Ge(B
e$B$”$l$P!“A4$F$N%P%j%(!<%7%g%s$K$D$$$F4|BT$9$k7k2L$r=q$+$;$F$”$2$F$be(B
e$B$h$$$N$G$O$J$$$G$9$+$M$(!#e(B

e$B%F%9%H$r=q$$$F=*$o$j$8$c$J$$$H$$$&;v$O0J>e$G$4M}2r$$$?$@$1$?;v$+$H;W$$$^$9!#e(B

e$B31$H$$$$$^$9!#e(B

On 2010/01/30, at 4:47, NARUSE, Yui wrote:

e$B$=$N%;%s%9$,$$$$$+$I$&$+$O$*$$$H$$$F!Ee(B

e$B%;%s%9$NLdBj$8$c$J$$$s$G$9$h!#e(B
RubySpec e$B$N:n$j<jC#$K$C$F!"H`$i$N%f!<%6$O0-L>9b$-e(B Rails e$B$J$o$1$G!"e(B
ERB#src e$B$@$m$&$,$J$s$@$m$&$,MF<O$J$/;H$C$F$-$^$9!#e(B
e$B$G$9$+$i!"8x3+e(B API e$B$J$i$P%F%9%H$9$k$N$OEvA3$G$9!#e(B

e$B$$$d!";H$C$F$[$7$$e(BAPIe$B$@$7%F%9%H$7$F$/$@$5$C$F$+$^$o$J$$$N$G$9$,!"e(B
e$BC1=c$KJ8;zNsHf3S$G8!::$9$k$+$iLdBj$J$s$G$9$h$M!#$?$V$s!#e(B

e$B$3$&$$$&%F%9%H$K$7$?J}$,$$$$$h!"$C$F$$$&$N$r65$($F$"$2$?$ie(B
e$B$h$$$N$+$J!#e(B

ERB#srce$B$N7k2L$NJ8;zNs$K6=L#$,$"$k?M$K$H$C$F$O!“0c$&$b$N$rJV$7$F$k$Ne(B
e$B$@$+$i!”;EMMJQ99$7$d$,$C$?$s$G$9$h$M!#e(B

MatzRuby e$B$O;EMMJQ99$N>l9g%"%W%j%1!<%7%g%sB&$KDI=>$rMW5a$9$kJ82=$G$9$,!"e(B
e$B8=>u8_49<BAu$ON)>l$,<e$$$N$G!#e(B

e$B$"$k%P!<%8%g%s$Ne(BERB#srce$B$H$^$?JL$N%P!<%8%g%s$Ne(BERB#srce$B$N5sF0$O0c$&$N$Ge(B
e$B$"$l$P!“A4$F$N%P%j%(!<%7%g%s$K$D$$$F4|BT$9$k7k2L$r=q$+$;$F$”$2$F$be(B
e$B$h$$$N$G$O$J$$$G$9$+$M$(!#e(B

e$B%F%9%H$r=q$$$F=*$o$j$8$c$J$$$H$$$&;v$O0J>e$G$4M}2r$$$?$@$1$?;v$+$H;W$$$^$9!#e(B

e$B$4$a$s$J$5$$!"$h$/$o$+$j$^$;$s$G$7$?!#e(B

e$B%P!<%8%g%s$4$H$K5sF0$K0c$$$"$k>l9g$K!"$=$l$>$l$N%P!<%8%g%s$4$H$Ne(B
e$B%F%9%H$r=q$/$N$O%@%a$C$F0UL#$G$9$+!)e(B

e$B$=$l$H$be(BRubySpece$B$r=q$$$F$k?M$?$A$H$b$C$H$o$+$j9g$o$J$$$H%@%a$C$Fe(B
e$B0UL#$G$9$+!)e(B

咳といいます。

On 2010/01/30, at 4:47, NARUSE, Yui wrote:

「変えない」と言った覚えはないわけですが、
公開APIである以上安易な仕様変更は慎む事が期待されます。
そもそも、Rails 以降 Ruby でも仕様変更は控えることが期待されつつあります。

では「慎むっていったのに変更しやがって!」でしょうか。
private constantがあれば
「変更しやがって!でもprivate constantだから勘弁してやる」
みたいな感じ?

どっちにしてもぎゃって思われそうだけどなあ。

“spec” ですし。
そもそも、RubySpec は誰のためのものかって、MRI のためじゃないんですよ。
JRuby や Rubinius、MacRuby、あと IronRuby のためのものです。
彼らが実装すべき「Ruby」の言語仕様を規定するのが RubySpec です。

言語仕様だとしたらPure Rubyなライブラリの挙動を
specに記述する必要あるのか疑問です。
だってそのままもってくれば同じように動くはずだもん。

あ。ちがうのかな。処理系が完全に移植されているかどうか
知りたいので、そのサンプルとしてライブラリの動きを
観察してるんでしょうかね。

それでも仕様変更であると宣言するならばもちろん変更は可能です。

わかりました。ありがとうございます。

e$B31$H$$$$$^$9!#e(B

On 2010/01/30, at 4:47, NARUSE, Yui wrote:

e$B%F%9%H$r=q$$$F=*$o$j$8$c$J$$$H$$$&;v$O0J>e$G$4M}2r$$$?$@$1$?;v$+$H;W$$$^$9!#e(B

e$B$"!#$b$7$+$7$F!“e(BRubye$B8_49$N=hM}7O$,$3$N%F%9%H$r$”$F$K$7$F$$$k$h!"e(B
e$B$H$$$&0UL#$G$7$g$&$+!)e(B

e$B$@$C$?$i$o$+$j$^$9!#$"$j$,$H$&$4$6$$$^$7$?!#e(B

On 1/28/10 8:55 PM, Yusuke ENDOH wrote:

Yugui e$B$5$s$NJV;v$O%a!<%k$G$OMh$F$$$^$;$s$,!"e(BIRC e$B$Ge(B

  • 1.9.2 e$B$G$Oe(B rb_classext_t e$B$NDj5A$Ke(B /** internal */ e$B$HIU$1$ke(B (e$B=hCV:Q$_e(B)
  • 1.9.3 e$B0J9_$G$3$NJQ99$rF~$l$ke(B

e$B$H$$$&H=CG$r$b$i$C$F$$$^$9!#e(B

e$B$G$9$,!":G6ae(B rubyspec e$B$KL$rDL$7$F$$$F!"$3$N5!G=$OAa$/F~$l$?J}$,$$$$$He(B
e$B;W$$$^$7$?!#e(B

e$B$O$$!#$^$:!“e(Brb_classext_te$B$O8x3+e(BAPIe$B$K4^$^$l$J$$$H$$$&G’<1$r3NG’$7$^$7$?!#e(B
e$B$=$N$?$ae(B/** @internal
*/e$B$rIU$1$^$7$?!#8x3+e(BAPIe$B$G$J$/!”%f!<%6!<B&$Ge(B
rb_classext_te$B$r3NJ]$9$kN`$N%^%/%m$b$J$$$N$G%a%s%P!<$rB-$9$N$OLdBj$"$j$^e(B
e$B$;$s!#e(B

e$B8@8l$N3HD%$J$N$G$A$g$C$H?5=E$K9T$-$?$$$H;W$C$Fe(B1.9.2e$B$G$O8+Aw$k$3$H$r9M$(e(B
e$B$^$7$?!#$7$+$7!"$b$&>/$79-$/e(B-coree$B$K$bOC$r?6$C$F0[O@$,$J$$$h$&$J$i$Pe(B1.9.2
e$B$KF~$l$F$b:9$7;Y$($J$$$G$9!#e(B

e$B1sF#$G$9!#e(B

2010e$BG/e(B1e$B7ne(B30e$BF|e(B14:34 Yugui (Yuki S.)
[email protected]:

e$B;W$$$^$7$?!#e(B

e$B$O$$!#$^$:!“e(Brb_classext_te$B$O8x3+e(BAPIe$B$K4^$^$l$J$$$H$$$&G’<1$r3NG’$7$^$7$?!#e(B
e$B$=$N$?$ae(B/** @internal */e$B$rIU$1$^$7$?!#8x3+e(BAPIe$B$G$J$/!”%f!<%6!<B&$Ge(B
rb_classext_te$B$r3NJ]$9$kN`$N%^%/%m$b$J$$$N$G%a%s%P!<$rB-$9$N$OLdBj$"$j$^e(B
e$B$;$s!#e(B

e$B8@8l$N3HD%$J$N$G$A$g$C$H?5=E$K9T$-$?$$$H;W$C$Fe(B1.9.2e$B$G$O8+Aw$k$3$H$r9M$(e(B
e$B$^$7$?!#$7$+$7!"$b$&>/$79-$/e(B-coree$B$K$bOC$r?6$C$F0[O@$,$J$$$h$&$J$i$Pe(B1.9.2
e$B$KF~$l$F$b:9$7;Y$($J$$$G$9!#e(B

e$B$"$j$,$H$&$4$6$$$^$9!#e(Bruby-core e$B$KEj$2$F$_$?$$$H;W$$$^$9!#e(B

e$B1sF#$G$9!#e(B

e$BBgBN@.@%$5$s$,JV;v$7$F$/$l$F$$$kDL$j$G$9$,!#e(B

2010e$BG/e(B1e$B7ne(B30e$BF|e(B7:08 Masatoshi SEKI
[email protected]:

e$B!VJQ99$7$d$,$C$F!$G$be(Bprivate constante$B$@$+$i4J[$7$F$d$k!We(B
e$B$_$?$$$J46$8!)e(B

e$B$I$C$A$K$7$F$b$.$c$C$F;W$o$l$=$&$@$1$I$J$"!#e(B

e$B$.$c$C$H$J$k$N$O!"$=$b$=$bFbIt%/%i%9$H$+ITMQ0U$K;H$&$+$i$G$9$h$M!#e(B
e$B;H$C$F$J$1$l$P$.$c$C$H$J$k$3$H$b$J$$$G$9!#e(B
e$B$J$<;H$C$F$7$^$&$+$H$$$&$H!"8@8l%l%Y%k$G$=$l$rCm0U4-5/$9$k;EAH$_$,e(B
e$B$J$$$+$i$@$H;W$&$N$G$9!#e(B

e$B$^$“!“e(B:nodoc:
e$B$C$F=q$$$F$”$l$P;H$&$J$h!D!D$H$$$&5$$b$9$k$N$G$9$,!“e(B
rubyspec e$B$,!Ve(Bprivate e$B$O;EMM$K$7$J$$!”$G$be(B :nodoc:
e$B$O;EMM$K$9$k!W$He(B
e$B$$$&N)>l$@$C$?$N$G!”$=$&9M$($k?M$bB?$$$s$G$7$g$&$M$(!#e(BRails
e$B$H$+!#e(B

e$B$“$H!”$h$/9M$($?$i!“31$5$s$,:G=i$K5$$K$7$F$$$?$N$O!”%f!<%6$,0lIt$Ne(B
API e$B$d<BAu$r>!<j$K:FDj5A$7$?>l9g$G$7$?$C$1!#$=$&$$$&$N$O$5$9$,$K!“e(B
e$B2?$,5/$-$F$b<+8J@UG$$H$$$&%3%s%;%s%5%9$,$”$k$H;W$$$^$9!#e(B

e$B8@8l;EMM$@$H$7$?$ie(BPure Rubye$B$J%i%$%V%i%j$N5sF0$re(B
spece$B$K5-=R$9$kI,MW$"$k$N$+5?Ld$G$9!#e(B
e$B$@$C$F$=$N$^$^$b$C$F$/$l$PF1$8$h$&$KF0$/$O$:$@$b$s!#e(B

spec e$B$J$N$G!“%i%$%V%i%j$Ne(B spec
e$B$r>$7$/CN$j$?$$$H$-$KFI$`$b$N!”$re(B
e$BL;X$7$F$b$$$k$h$&$G$9e(B
(e$B8=>u$=$l$,C#@.$5$l$F$$$k$+$O$5$F$*$-e(B) e$B!#e(B
e$B!V%3!<%I$,;EMM!W$G$O$J$/$F!#e(B

e$B$^$?!“:GE,2=$dFH<+3HD%$r$9$k$H$-$Ke(B conformance test
e$B$K$b;H$($k$He(B
e$B;W$$$^$9!#$=$N$?$a$Ke(B rubyspec
e$B$G$O!”!V0z?t$r$o$6$HB?$/M?$($?$H$-$Ke(B
e$BNc30$,Ej$2$i$l$k!W$_$?$$$J!"FH<+3HD%$rK8$2$k$h$&$Je(B spec
e$B$O=q$+$J$$!"e(B
e$B$H$$$&J}?K$K$J$C$F$^$9e(B
(e$B8=>u$=$l$,C#@.$5$l$F$$$k$+$O$5$F$*$-e(B) e$B!#e(B

e$B$=$l$G$b;EMMJQ99$G$"$k$H@k8@$9$k$J$i$P$b$A$m$sJQ99$O2DG=$G$9!#e(B

e$B$o$+$j$^$7$?!#$"$j$,$H$&$4$6$$$^$9!#e(B

e$B2DG=$G$O$"$j$^$9$,!“6KNOHr$1$k$Y$-$G$O$”$j$^$9!#e(B

e$B1sF#$G$9!#e(B

2010e$BG/e(B1e$B7ne(B30e$BF|e(B7:20 Masatoshi SEKI
[email protected]:

e$BIaDL$K8+$($k$b$N$O2?$G$be(B spec e$B$K$5$l$F$7$^$&Nc$H$7$F!“0J2<$N$h$&$Je(B spec
e$B$,$”$j$^$9!#e(B(private constant e$B$K$O4X78$J$$$G$9$,!D!De(B)

http://github.com/rubyspec/rubyspec/blob/master/library/erb/src_spec.rb

e$B$D$^$j!“e(BERB#src e$B$NJV$jCM$r8GDjJ8;zNs$Ge(B spec e$B$K$7$F$$$k$H$$$&!#e(B1.9 e$B$G<:GTe(B
e$B$7$F$k$s$G$9$,!”$I$&BP=h$7$?$b$N$G$7$g$&!#e(B

e$B$$$d!";H$C$F$[$7$$e(BAPIe$B$@$7%F%9%H$7$F$/$@$5$C$F$+$^$o$J$$$N$G$9$,!"e(B

e$B=c?h$K8x3+e(B API
e$B$J$s$G$9$M!#A[DjMQES$O!"%3%s%Q%$%k7k2L$N%-%c%C%7%e!)e(B
e$B$@$H$7$?$ie(B Proc e$B$H$+JV$7$?J}$,$h$+$C$?5$$b$7$^$9e(B (ERB
e$B3+H/Ev;~$Ne(B
Ruby e$B$N>u67$rCN$i$J$$$G$9$,e(B) e$B!#e(B

e$B$$$:$l$K$;$h8x3+e(B API e$B$J$i!"e(Bspec
e$B$K=q$/$N$,$h$5$=$&$G$9!#$=$l$J$i!"e(B

e$BC1=c$KJ8;zNsHf3S$G8!::$9$k$+$iLdBj$J$s$G$9$h$M!#$?$V$s!#e(B

e$B$=$&$$$&LdBj$@$H;W$$$^$9!#e(BERB#src
e$B$O!V$3$&$$$&>r7o2<$G$3$&$$$&e(B
e$BJ8;zNs$rJV$94X?t!W$H$$$&;EMM$G$O$J$$!"$H$$$&$3$H$G!"e(B

e$B$3$&$$$&%F%9%H$K$7$?J}$,$$$$$h!“$C$F$$$&$N$r65$($F$”$2$?$ie(B
e$B$h$$$N$+$J!#e(B

e$B$=$l$,$$$$$H;W$$$^$9!#@53N$K$O!Ve(BERB#src
e$B$O$I$&$$$&;EMM$+!W$r65$($Fe(B
e$B$"$2$k$H$$$$$H;W$$$^$9!#e(B

e$B?d;!$9$k$K!"!V<B9T2DG=$Je(B Ruby
e$B%3!<%I$NJ8;zNs$rJV$9!W$H$$$&$N$,;EMMe(B
e$B$G$7$g$&$+!#$@$H$9$l$P!"J8;zNs$NCf?H$r8+$k$N$G$O$J$/!"e(Bripper
e$B$Ge(B
e$B%Q!<%9$,DL$k$3$H$r$$k$H$+!"<B:]$Ke(B eval e$B$7$F$$k$N$,@5$7$$e(B
spec e$B$Ne(B
e$B%F%9%H$H8@$($=$&$G$9!#e(B

e$B31$H$$$$$^$9!#e(B

On 2010/01/30, at 20:02, Yusuke ENDOH wrote:

e$B$$$d!";H$C$F$[$7$$e(BAPIe$B$@$7%F%9%H$7$F$/$@$5$C$F$+$^$o$J$$$N$G$9$,!"e(B

e$B=c?h$K8x3+e(B API e$B$J$s$G$9$M!#A[DjMQES$O!"%3%s%Q%$%k7k2L$N%-%c%C%7%e!)e(B
e$B$@$H$7$?$ie(B Proc e$B$H$+JV$7$?J}$,$h$+$C$?5$$b$7$^$9e(B (ERB e$B3+H/Ev;~$Ne(B
Ruby e$B$N>u67$rCN$i$J$$$G$9$,e(B) e$B!#e(B

e$B$J$<8=:_$Ne(BRubye$B$N>u67$G$Oe(BProce$B$NJ}$,$h$$$N$G$9$+!)e(B
e$B;d$Oe(B1.9.xe$B$G$=$&JQ99$9$Y$-$G$7$g$&$+!)e(B

ERBe$B$Oe(BeRubye$B$N%9%/%j%W%H$+$ie(BRubye$B$N%9%/%j%W%H$X$NJQ49$rC4Ev$7$^$9!#e(B
ERB#srce$B$3$=$,K\Mh$d$j$?$+$C$?$b$N$G$9!#e(B
bin/erbe$B$de(BERB#run,
resulte$B$O$I$A$i$+$H8@$($P%5%s%W%k%3!<%I$G$9!#e(B

e$BJQ497k2L$r%U%!%$%k$r=q$/?M$b$$$k$h$&$G$9$,!"e(BProce$B$r:n$k$J$je(B
e$B9%$-$K;H$($P$h$$$H;W$$$^$9!#e(B

e$B$b$7$b:n<T$N0U?^$r$/$s$G$/$l$k$J$i!“%a%=%C%IDj5A$N<j=u$1$K;H$C$Fe(B
e$B$[$7$$$N$G$9$,!”%f!<%6$,$=$s$J0U?^$K4X78$J$/9%$-$K;H$($k$N$,e(B
e$B$+$J$7$/$F$*$b$7$m$$$H$3$m$G$9$h$M!#e(B

e$BB@8E$N;qNA$G$h$1$l$P$3$s$J$N$,$"$j$^$7$?!#e(B
http://www.druby.org/ilikeruby/erbway.html

e$B$3$&$$$&%F%9%H$K$7$?J}$,$$$$$h!“$C$F$$$&$N$r65$($F$”$2$?$ie(B
e$B$h$$$N$+$J!#e(B

e$B$=$l$,$$$$$H;W$$$^$9!#@53N$K$O!Ve(BERB#src e$B$O$I$&$$$&;EMM$+!W$r65$($Fe(B
e$B$"$2$k$H$$$$$H;W$$$^$9!#e(B

e$B?d;!$9$k$K!"!V<B9T2DG=$Je(B Ruby e$B%3!<%I$NJ8;zNs$rJV$9!W$H$$$&$N$,;EMMe(B
e$B$G$7$g$&$+!#$@$H$9$l$P!"J8;zNs$NCf?H$r8+$k$N$G$O$J$/!"e(Bripper e$B$Ge(B
e$B%Q!<%9$,DL$k$3$H$r$$k$H$+!"<B:]$Ke(B eval e$B$7$F$$k$N$,@5$7$$e(B spec e$B$Ne(B
e$B%F%9%H$H8@$($=$&$G$9!#e(B

e$B$$$(!"<B9T2DG=$Je(BRubye$B%3!<%I$+$I$&$+$O!"85$NJ8;zNs$K$h$k$N$Ge(B
e$B$o$+$i$J$$$H;W$$$^$9!#e(B

e$B<B:]$Ke(Bevale$B$r$9$ke(Bresulte$B$r8F$V$N$,4JC1$G$7$g$&$1$I!"e(B
e$B$=$l$,5$$KF~$i$J$$$J$i!"L@<(E*$Ke(Bevale$B$9$k$N$,$$$$$He(B
e$B;W$$$^$9!#e(B

e$B$“!<!”$G$be(Brubyspece$B$C$FK\Ev$O$J$K$r%F%9%H$7$?$$$s$@$m$&!#e(B
e$B%F%9%H$8$c$J$$$s$G$7$?$M!#;EMM$+!#e(B
e$B;EMM$C$F$$$&$N$O$$$D$b%F%9%H%3!<%I$K=q$1$k$s$G$9$+$M$(!#e(B
e$B$H$$$&$+%F%9%H%3!<%I$K$“$k%1!<%9$@$1$r%Q%9$9$k$N$,;EMM$J$N$+$J$”!#e(B

e$B$9$_$^$;$s!"C&@~$7$^$7$?e(B

e$B$O$?$7$F!“K\Ev$K$”$N$H$-$H%P!<%8%g%s$H$3$N$H$-$N%P!<%8%g%s$,e(B
e$BJV$9J8;zNs$,0c$&$K$b4X$o$i$:!"$=$&$$$&$3$H$r5-=R$7$J$/$F$be(B
e$B$h$$$N$G$7$g$&$+!#e(B

e$B$=$NJ8;zNs$NJQ2=$K$h$C$F!“$*$+$7$J%f!<%6$N%3!<%I$,4qL/$Je(B
e$B5sF0$r<($9$3$H$b$”$k$H;W$$$^$9$,!“$=$&$$$&$N$rD4$Y$k<j$,$+$je(B
e$B$J$j$=$&$K;W$&$s$@$1$I$J$”!#e(B

e$B$=$&$$$&%;%s%5!<$G$O$J$$$J$i!“$^!”$$$C$+!#e(B
e$B;~4V$H855$$,$"$k$H$-$K!“e(Bevale$B$9$k$h$&$J%F%9%H%1!<%9$rDs0F$7$F$_$^$9!#e(B
e$B1Q8l$G0U?^$r@bL@$9$k$N$O;d$K$OL5M}$J$N$G!”%3!<%IAw$j$^$9!#$?$V$s!#e(B

e$BB?$/$NJ}$K$4LBOG$*$+$1$7$F?=$7Lu$"$j$^$;$s$G$7$?!#e(B

e$B31$H$$$$$^$9!#e(B

On 2010/01/30, at 19:49, Yusuke ENDOH wrote:

e$B$=$l$G$b;EMMJQ99$G$"$k$H@k8@$9$k$J$i$P$b$A$m$sJQ99$O2DG=$G$9!#e(B

e$B$o$+$j$^$7$?!#$"$j$,$H$&$4$6$$$^$9!#e(B

e$B2DG=$G$O$"$j$^$9$,!“6KNOHr$1$k$Y$-$G$O$”$j$^$9!#e(B

e$B$O$$!#I8=`E:IU$K$7$?$H$-$+$i!"$=$N$D$b$j$G$9!#e(B

e$B;d$K$O5sF0$rA4$/JQ$($:$KIT6q9g$rD>$7$?$j!"e(B
e$B@-G=$r2~A1$7$?$j$9$k$3$H$O$G$-$J$$$N$G!"e(B
e$B;EMM$rJQ99$7$J$$$HLsB+$O$G$-$J$$$s$G$9!#e(B
e$B$=$l$G3NG’$7$F$_$^$7$?!#e(B

e$B31$5$se(B
e$B1sF#$G$9!#e(B

2010e$BG/e(B1e$B7ne(B30e$BF|e(B22:45 Yusuke ENDOH [email protected]:

rubyspec e$B$O!Ve(BMRI e$B$HE:IU%i%$%V%i%j$N>:Y;EMM!W$G$O$J$/!"!Ve(BRuby e$B8@8l$He(B
e$BI8=`%i%$%V%i%j$N30It;EMM!W$r=q$/$3$H$rL\E*$H$7$F$$$^$9!#e(B

e$BCN$C$?$+$G$$$m$$$m$$$$$^$7$?$,!"e(Brubyspec
e$B$N?M$rFM$C$D$$$F$_$?$H$3$m!"e(B
[ruby-core:28010] e$B$H$$$&2sEz$,$-$^$7$?!#e(B

e$B%5!<%I%Q!<%F%#$Ne(B Ruby e$B%3!<%I$,!Ve(BRuby
e$B<BAu!We(B(e$B$?$V$sI8=E:IU%i%$%V%i%j$be(B e$B4^$e(B) e$B$K4|BT$9$k$3$H$r=q$-=P$7$?$$!#$=$N$?$a$Ke(B MRI
e$B$N%F%9%H$+$ie(B (?) e$B!“e(B
e$B%[%o%$%H%%C%/%9%F%9%H!“2s5”%F%9%H!”%9%H%l%9%F%9%H$J$I$r=|$$$?%F%9%He(B
(e$BMW$9$k$Ke(B conformance test e$B$H$7$F;H$($k$b$Ne(B) e$B$r:n$k!#e(B
e$B$i$7$$$G$9!#e(B

e$B$4;29M$^$G!#e(B

e$B1sF#$G$9!#e(B

2010e$BG/e(B1e$B7ne(B30e$BF|e(B21:39 Masatoshi SEKI
[email protected]:

e$B$J$<8=:_$Ne(BRubye$B$N>u67$G$Oe(BProce$B$NJ}$,$h$$$N$G$9$+!)e(B
e$B;d$Oe(B1.9.xe$B$G$=$&JQ99$9$Y$-$G$7$g$&$+!)e(B

ERBe$B$Oe(BeRubye$B$N%9%/%j%W%H$+$ie(BRubye$B$N%9%/%j%W%H$X$NJQ49$rC4Ev$7$^$9!#e(B
ERB#srce$B$3$=$,K\Mh$d$j$?$+$C$?$b$N$G$9!#e(B

e$B:n$C$F$$$k$H[#Kf$K$J$j$,$A$G$9$,!“!Ve(BERB
e$B$N8@8l$r<B9T$9$k!W$,L\E*$Ge(B
e$B$”$j!“!Ve(BERB e$B$N8@8l$KAjEv$9$ke(B
Rubye$B%3!<%I$r9g@.$9$k!W$O$”$/$^$G<jCJe(B
e$B$G$O$J$$$G$7$g$&$+!#e(B
e$B$3$NL\E*$rC#@.$9$k$?$a$K!“<jCJ$N>:Y$r2<<j$K$5$i$1=P$9$H!”>-Mh$Ne(B
e$B2~NI$d%P%0=$@5$G;EMM$rJQ99$9$k$3$H$K$J$k%j%9%/$,9b$$$H;W$C$?$?$ae(B
Proc e$B$NJ}$,$$$$$H$$$$$^$7$?!#e(B

e$B$G$b!"e(BProc e$B$K$9$k$He(B

e$BJQ497k2L$r%U%!%$%k$r=q$/?M$b$$$k$h$&$G$9$,!"e(BProce$B$r:n$k$J$je(B
e$B9%$-$K;H$($P$h$$$H;W$$$^$9!#e(B

Proc e$B$Oe(B Marshal
e$B$G$-$J$$$+$i%U%!%$%k$K=q$-=P$9$H$$$&%f!<%9%1!<%9$,e(B
e$BK~$?$;$J$/$J$j$^$9$M!#$9$_$^$;$s!#e(B

e$B?d;!$9$k$K!"!V<B9T2DG=$Je(B Ruby e$B%3!<%I$NJ8;zNs$rJV$9!W$H$$$&$N$,;EMMe(B
e$B$G$7$g$&$+!#e(B

e$B$$$(!"<B9T2DG=$Je(BRubye$B%3!<%I$+$I$&$+$O!"85$NJ8;zNs$K$h$k$N$Ge(B
e$B$o$+$i$J$$$H;W$$$^$9!#e(B

e$B$b$&$A$g$C$H8@$&$H!Ve(BERB
e$B8@8l$H$7$F@5$7$$5-=R$,F~NO$5$l$?$i!“<B9Te(B
e$B2DG=$Je(B Ruby e$B%3!<%I$NJ8;zNs$rJV$9!W$G$9$+$M!#e(B
e$B!Ve(BERB
e$B8@8l$H$7$F@5$7$$5-=R!W$C$F$J$s$@!”$H$$$&$3$H$K$J$j$^$9$,!#e(B

e$B$“!<!”$G$be(Brubyspece$B$C$FK\Ev$O$J$K$r%F%9%H$7$?$$$s$@$m$&!#e(B
e$B%F%9%H$8$c$J$$$s$G$7$?$M!#;EMM$+!#e(B
e$B;EMM$C$F$$$&$N$O$$$D$b%F%9%H%3!<%I$K=q$1$k$s$G$9$+$M$(!#e(B

e$B=q$1$J$$$G$9$M!#6KC<$JNc$G$O!"e(BString#dump e$B$O!VI,$:Dd;$9$ke(B
Ruby
e$B%3!<%I$r=PNO$9$k!W$H$$$&;EMM$,$"$k$H;W$o$l$^$9$,!"Dd;
@-H=Dj$Oe(B
e$B7hDjITG=$J$N$GH=Dj$G$-$J$$$G$9!#e(B

e$B$H$$$&$+%F%9%H%3!<%I$K$“$k%1!<%9$@$1$r%Q%9$9$k$N$,;EMM$J$N$+$J$”!#e(B

rubyspec e$B$O@53N$K$O!"!Ve(BRuby
e$B=hM}7O$,K~$?$9$Y$-;EMM!W$H!V;EMM$Ke(B
e$B1h$C$F$$$k$3$H$r$6$C$H%A%'%C%/$9$ke(B conformance
teste$B!W$NAH$G$9!#e(B
rubyspec e$B$O<B:]$K$Oe(B

describe “Array#zip” do
it “returns an array of arrays containing corresponding elements of
each array” do
[1, 2, 3, 4].zip([“a”, “b”, “c”, “d”, “e”]).should ==
[[1, “a”], [2, “b”], [3, “c”], [4, “d”]]
end
end

e$B$_$?$$$K=q$+$l$F$$$^$9!#$3$NCf$G!V;EMM!W$J$N$O!"e(B

Array#zip returns an array of arrays containing corresponding elements
of each array

e$B$N<+A38@8l$NItJ,$G$9!#%V%m%C%/Cf$K$"$k$N$,!Ve(Bconformance
teste$B!We(B
e$B$G$9!#e(B

e$B$O$?$7$F!“K\Ev$K$”$N$H$-$H%P!<%8%g%s$H$3$N$H$-$N%P!<%8%g%s$,e(B
e$BJV$9J8;zNs$,0c$&$K$b4X$o$i$:!"$=$&$$$&$3$H$r5-=R$7$J$/$F$be(B
e$B$h$$$N$G$7$g$&$+!#e(B

e$B$J$s$+$o$+$C$F$-$^$7$?!#$=$l$OB?J,@_7W;EMM$H$+>:Y;EMM$H$+8@$o$l$ke(B
e$B$b$N$G$9$M!#e(B

rubyspec e$B$O!Ve(BMRI
e$B$HE:IU%i%$%V%i%j$N>:Y;EMM!W$G$O$J$/!“!Ve(BRuby e$B8@8l$He(B
e$BI8=%i%$%V%i%j$N30It;EMM!W$r=q$/$3$H$rL\E*$H$7$F$$$^$9!#e(B e$B!V$3$l$rK~$?$7$F$$$l$Pe(B Ruby e$B$rL>>h$C$F$$$$$h!W$H$$$&4p=$J$N$G!“e(B
e$B<BAuJ}K!$J$I:Y$+$$$3$H$r5,Dj$7$9$.$k$H!”$”$ke(B OS e$B$G$Oe(B Ruby
e$B$rL>>h$ke(B
e$B%W%m%0%i%`$r:n$l$J$$$H$+!“:GE,2=$7$?$ie(B Ruby
e$B$rL>>h$l$J$/$J$C$?$H$+!“e(B
e$BLdBj$,5/$3$j$^$9$N$G!”$”$kDxEY<+M3EY$N$“$k;EMM$K$9$kI,MW$,$”$j$^$9!#e(B

e$B$H$$$C$F$b!"0J>e$O;d$NM}2r$J$N$G!"4V0c$C$F$$$k$+$b$7$l$^$;$s!#e(B

rubyspec e$B$O!Ve(BRuby

e$B$N%P!<%8%g%s4V$N0c$$$rLVMe$9$k!W$H$$$&%5%V$Ne(B

e$BL\E*$b7G$2$F$$$?5$$,$9$k$N$G!"$=$C$A$N0UL#$G$O=q$$$?J}$,$$$$$N$+$b!#e(B

e$B$=$NJ8;zNs$NJQ2=$K$h$C$F!“$*$+$7$J%f!<%6$N%3!<%I$,4qL/$Je(B
e$B5sF0$r<($9$3$H$b$”$k$H;W$$$^$9$,!“$=$&$$$&$N$rD4$Y$k<j$,$+$je(B
e$B$J$j$=$&$K;W$&$s$@$1$I$J$”!#e(B

e$B$=$&$$$&%;%s%5!<$G$O$J$$$J$i!“$^!”$$$C$+!#e(B

e$B$=$l$O$=$l$G2ACM$,$"$k$b$N$G$9$,!"e(Brubyspec e$B$G$O$J$/e(B test/
e$B0J2<$KCV$/e(B
e$B$H$$$$$H;W$$$^$9!#e(B

e$B;~4V$H855$$,$"$k$H$-$K!“e(Bevale$B$9$k$h$&$J%F%9%H%1!<%9$rDs0F$7$F$_$^$9!#e(B
e$B1Q8l$G0U?^$r@bL@$9$k$N$O;d$K$OL5M}$J$N$G!”%3!<%IAw$j$^$9!#$?$V$s!#e(B

e$BB?$/$NJ}$K$4LBOG$*$+$1$7$F?=$7Lu$"$j$^$;$s$G$7$?!#e(B

e$B$$$(!"A4$/LBOG$G$O$J$$$G$9!#e(B
ERB e$B$N@_7W0U?^$,$$$m$$$m$o$+$C$?$N$G;29M$K$J$j$^$7$?!#e(B

e$B31$5$se(B
e$B1sF#$G$9!#e(B

2010e$BG/e(B1e$B7ne(B30e$BF|e(B21:39 Masatoshi SEKI
[email protected]:

e$B;~4V$H855$$,$"$k$H$-$K!“e(Bevale$B$9$k$h$&$J%F%9%H%1!<%9$rDs0F$7$F$_$^$9!#e(B
e$B1Q8l$G0U?^$r@bL@$9$k$N$O;d$K$OL5M}$J$N$G!”%3!<%IAw$j$^$9!#$?$V$s!#e(B

eval e$B$9$k$h$&$Je(B spec e$B$K=q$-$J$*$7$F8+$^$7$?!#e(B

e$B;d$Oe(B rubyspec
e$B$N%3%%C%H8"$r;}$C$F$$$k$N$G!"31$5$s$5$($h$1$l$P$9$0$Ke(B
e$B%3%
%C%H$7$F$7$^$$$^$9$,!"$h$m$7$$$G$7$g$&$+!#e(B

diff --git a/library/erb/src_spec.rb b/library/erb/src_spec.rb
index 8ea89b5…7b11041 100644
— a/library/erb/src_spec.rb
+++ b/library/erb/src_spec.rb
@@ -3,51 +3,30 @@ require File.dirname(FILE) + ‘/…/…/spec_helper’

describe “ERB#src” do

  • ruby_version_is “” … “1.8.7” do
  • it “returns the compiled ruby code” do
  •  input = <<'END'
    
  • it “returns the compiled ruby code evaluated to a string” do
  • note that what concrete code is emitted is not guaranteed.

  • input = <<‘END’
    <% for item in list %>
  • <%= item %>
  • <% end %>
END - expected = <<'END' -_erbout = ''; _erbout.concat "
    \n" - for item in list ; _erbout.concat "\n" -_erbout.concat "
  • "; _erbout.concat(( item ).to_s); _erbout.concat "
  • \n" - end ; _erbout.concat "\n" -_erbout.concat "
\n" -_erbout -END - - expected.chomp! - ERB.new(input).src.should == expected - end - end
  • ruby_version_is “1.8.7” do
  • it “returns the compiled ruby code” do
  •  input = <<'END'
    
  • expected = <<‘END’
    -<% for item in list %> -
  • <%= item %>
  • -<% end %> -
-END
  •  expected = <<EOS
    

-_erbout = ‘’; _erbout.concat “

    \n”
    -; for item in list ; _erbout.concat “\n

  • -; _erbout.concat(( item ).to_s); _erbout.concat “
  • \n”
    -; end ; _erbout.concat “\n
\n”
+
  • 1
  • -; _erbout
    -EOS
    +

  • 2
    •  expected.chomp!
      
    •  ERB.new(input).src.should == expected
      
    • end
      +
    • 3

    +
    +END

    • list = [1, 2, 3]
    • eval(ERB.new(input).src).should == expected
      end

    end