* eval.c (rb_mod_define_method): should save safe_level in the

proc object.  [ruby-dev:28146]

* test/drb/drbtest.rb (DRbService::self.ext_service): increase
  timeout limit.  a patch from Kazuhiro NISHIYAMA
  <zn at mbf.nifty.com>. [ruby-dev:28132]

* eval.c (ev_const_get): fixed a bug in constant reference during
  instance_eval.  [yarv-dev:707]

* eval.c (ev_const_defined): ditto.

* lib/yaml.rb (YAML::add_domain_type): typo fixed.  a patch from
  Joel VanderWerf <vjoel at path.berkeley.edu>.
  [ruby-talk:165285] [ruby-core:6995]

* ext/digest/sha2/sha2.c (ULL): support AIX C.  a patch from
  Kailden <kailden at gmail.com>.  [ruby-core:06984]

* ext/syck/rubyext.c (rb_syck_compile): avoid potential memory
  leak.

* ext/syck/rubyext.c (syck_set_ivars): avoid potential memory
  leak by explicit symbol allocation.

* lib/delegate.rb (Delegator::method_missing): should delegate
  block as well.

* lib/cgi.rb (CGI::QueryExtension::MorphingBody): fix criteria to
  use Tempfile.  A fix from Zev Blut <rubyzbibd at ubit.com>.
  [ruby-core:06076]

* string.c: remove global functions work on $_.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9757 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2005-12-29 12:05:16 +00:00
parent e5226ea394
commit de3bff164c
13 changed files with 342 additions and 370 deletions

View File

@ -3,6 +3,11 @@ Thu Dec 29 17:02:07 2005 Tanaka Akira <akr@m17n.org>
* test/ruby/envutil.rb (EnvUtil.rubybin): search "ruby" instead of * test/ruby/envutil.rb (EnvUtil.rubybin): search "ruby" instead of
"miniruby". [ruby-dev:28140] "miniruby". [ruby-dev:28140]
Thu Dec 29 14:35:10 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (rb_mod_define_method): should save safe_level in the
proc object. [ruby-dev:28146]
Thu Dec 29 11:22:34 2005 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp> Thu Dec 29 11:22:34 2005 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
* lib/generator.rb: reimplemented Generator class with Thread instead of * lib/generator.rb: reimplemented Generator class with Thread instead of
@ -23,6 +28,12 @@ Tue Dec 27 23:59:53 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/optparse.rb (CompletingHash#match): fix for 1.9. * lib/optparse.rb (CompletingHash#match): fix for 1.9.
Tue Dec 27 16:59:52 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* test/drb/drbtest.rb (DRbService::self.ext_service): increase
timeout limit. a patch from Kazuhiro NISHIYAMA
<zn at mbf.nifty.com>. [ruby-dev:28132]
Tue Dec 27 14:17:55 2005 Tanaka Akira <akr@m17n.org> Tue Dec 27 14:17:55 2005 Tanaka Akira <akr@m17n.org>
* configure.in: define IA64 for portability. (HP aC++/ANSI C doesn't * configure.in: define IA64 for portability. (HP aC++/ANSI C doesn't
@ -74,6 +85,22 @@ Tue Dec 27 08:22:15 2005 GOTOU Yuuzou <gotoyuzo@notwork.org>
* ext/openssl/lib/openssl/ssl.rb (OpenSSL::SSL::SSLSocket#post_connection_chech): * ext/openssl/lib/openssl/ssl.rb (OpenSSL::SSL::SSLSocket#post_connection_chech):
treat wildcard character in commonName. [ruby-dev:28121] treat wildcard character in commonName. [ruby-dev:28121]
Mon Dec 26 08:50:36 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (ev_const_get): fixed a bug in constant reference during
instance_eval. [yarv-dev:707]
* eval.c (ev_const_defined): ditto.
* lib/yaml.rb (YAML::add_domain_type): typo fixed. a patch from
Joel VanderWerf <vjoel at path.berkeley.edu>.
[ruby-talk:165285] [ruby-core:6995]
Fri Dec 23 10:30:23 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* ext/digest/sha2/sha2.c (ULL): support AIX C. a patch from
Kailden <kailden at gmail.com>. [ruby-core:06984]
Wed Dec 21 16:47:35 2005 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp> Wed Dec 21 16:47:35 2005 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
* file.c (w32_io_info): should return handle because FileIndex is * file.c (w32_io_info): should return handle because FileIndex is
@ -179,6 +206,14 @@ Sat Dec 17 21:50:41 2005 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
* ext/syck/rubyext.c (syck_mark_parser): should mark anchor nodes * ext/syck/rubyext.c (syck_mark_parser): should mark anchor nodes
because they hold ruby objects. (ie: rb_syck_bad_anchor_handler) because they hold ruby objects. (ie: rb_syck_bad_anchor_handler)
Sat Dec 17 11:00:17 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* ext/syck/rubyext.c (rb_syck_compile): avoid potential memory
leak.
* ext/syck/rubyext.c (syck_set_ivars): avoid potential memory
leak by explicit symbol allocation.
Sat Dec 17 03:57:01 2005 Tanaka Akira <akr@m17n.org> Sat Dec 17 03:57:01 2005 Tanaka Akira <akr@m17n.org>
* bignum.c (rb_big_rshift): fix a GC problem on * bignum.c (rb_big_rshift): fix a GC problem on
@ -206,6 +241,19 @@ Fri Dec 16 11:44:43 2005 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
... these fixes won't fix [ruby-dev:27839]. more work is needed. ... these fixes won't fix [ruby-dev:27839]. more work is needed.
Fri Dec 16 04:38:55 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* lib/delegate.rb (Delegator::method_missing): should delegate
block as well.
Thu Dec 15 19:57:12 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* lib/cgi.rb (CGI::QueryExtension::MorphingBody): fix criteria to
use Tempfile. A fix from Zev Blut <rubyzbibd at ubit.com>.
[ruby-core:06076]
* string.c: remove global functions work on $_.
Thu Dec 15 12:35:14 2005 Yukihiro Matsumoto <matz@ruby-lang.org> Thu Dec 15 12:35:14 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* lib/tmpdir.rb: merged RDoc patch from Eric Hodel <drbrain at * lib/tmpdir.rb: merged RDoc patch from Eric Hodel <drbrain at

112
enum.c
View File

@ -570,9 +570,9 @@ all_i(VALUE i, VALUE *memo)
* <code>all?</code> will return <code>true</code> only if none of the * <code>all?</code> will return <code>true</code> only if none of the
* collection members are <code>false</code> or <code>nil</code>.) * collection members are <code>false</code> or <code>nil</code>.)
* *
* %w{ ant bear cat}.all? {|word| word.length >= 3} #=> true * %w{ant bear cat}.all? {|word| word.length >= 3} #=> true
* %w{ ant bear cat}.all? {|word| word.length >= 4} #=> false * %w{ant bear cat}.all? {|word| word.length >= 4} #=> false
* [ nil, true, 99 ].all? #=> false * [ nil, true, 99 ].all? #=> false
* *
*/ */
@ -617,9 +617,9 @@ any_i(VALUE i, VALUE *memo)
* of the collection members is not <code>false</code> or * of the collection members is not <code>false</code> or
* <code>nil</code>. * <code>nil</code>.
* *
* %w{ ant bear cat}.any? {|word| word.length >= 3} #=> true * %w{ant bear cat}.any? {|word| word.length >= 3} #=> true
* %w{ ant bear cat}.any? {|word| word.length >= 4} #=> true * %w{ant bear cat}.any? {|word| word.length >= 4} #=> true
* [ nil, true, 99 ].any? #=> true * [ nil, true, 99 ].any? #=> true
* *
*/ */
@ -632,6 +632,104 @@ enum_any(VALUE obj)
return result; return result;
} }
static VALUE
one_iter_i(VALUE i, VALUE *memo)
{
if (RTEST(rb_yield(i))) {
if (*memo == Qundef) {
*memo = Qtrue;
}
else if (*memo == Qtrue) {
*memo = Qfalse;
}
}
return Qnil;
}
static VALUE
one_i(VALUE i, VALUE *memo)
{
if (RTEST(i)) {
if (*memo == Qundef) {
*memo = Qtrue;
}
else if (*memo == Qtrue) {
*memo = Qfalse;
}
}
return Qnil;
}
/*
* call-seq:
* enum.one? [{|obj| block }] => true or false
*
* Passes each element of the collection to the given block. The method
* returns <code>true</code> if the block returns <code>true</code>
* exactly once. If the block is not given, <code>one?</code> will return
* <code>true</code> only if exactly one of the collection members are
* true.
*
* %w{ant bear cat}.one? {|word| word.length == 4} #=> true
* %w{ant bear cat}.one? {|word| word.length >= 4} #=> false
* [ nil, true, 99 ].one? #=> true
*
*/
static VALUE
enum_one(VALUE obj)
{
VALUE result = Qundef;
rb_iterate(rb_each, obj, rb_block_given_p() ? one_iter_i : one_i, (VALUE)&result);
if (result == Qundef) return Qfalse;
return result;
}
static VALUE
none_iter_i(VALUE i, VALUE *memo)
{
if (RTEST(rb_yield(i))) {
*memo = Qfalse;
rb_iter_break();
}
return Qnil;
}
static VALUE
none_i(VALUE i, VALUE *memo)
{
if (RTEST(i)) {
*memo = Qfalse;
rb_iter_break();
}
return Qnil;
}
/*
* call-seq:
* enum.none? [{|obj| block }] => true or false
*
* Passes each element of the collection to the given block. The method
* returns <code>true</code> if the block never returns <code>true</code>
* for all elements. If the block is not given, <code>one?</code> will return
* <code>true</code> only if any of the collection members is true.
*
* %w{ant bear cat}.one? {|word| word.length == 4} #=> true
* %w{ant bear cat}.one? {|word| word.length >= 4} #=> false
* [ nil, true, 99 ].one? #=> true
*
*/
static VALUE
enum_none(VALUE obj)
{
VALUE result = Qtrue;
rb_iterate(rb_each, obj, rb_block_given_p() ? none_iter_i : none_i, (VALUE)&result);
return result;
}
static VALUE static VALUE
min_i(VALUE i, VALUE *memo) min_i(VALUE i, VALUE *memo)
{ {
@ -998,6 +1096,8 @@ Init_Enumerable(void)
rb_define_method(rb_mEnumerable,"partition", enum_partition, 0); rb_define_method(rb_mEnumerable,"partition", enum_partition, 0);
rb_define_method(rb_mEnumerable,"all?", enum_all, 0); rb_define_method(rb_mEnumerable,"all?", enum_all, 0);
rb_define_method(rb_mEnumerable,"any?", enum_any, 0); rb_define_method(rb_mEnumerable,"any?", enum_any, 0);
rb_define_method(rb_mEnumerable,"one?", enum_one, 0);
rb_define_method(rb_mEnumerable,"none?", enum_none, 0);
rb_define_method(rb_mEnumerable,"min", enum_min, 0); rb_define_method(rb_mEnumerable,"min", enum_min, 0);
rb_define_method(rb_mEnumerable,"max", enum_max, 0); rb_define_method(rb_mEnumerable,"max", enum_max, 0);
rb_define_method(rb_mEnumerable,"min_by", enum_min_by, 0); rb_define_method(rb_mEnumerable,"min_by", enum_min_by, 0);

35
eval.c
View File

@ -373,7 +373,6 @@ static ID init, eqq, each, aref, aset, match, missing;
static ID added, singleton_added; static ID added, singleton_added;
static ID __id__, __send__, respond_to; static ID __id__, __send__, respond_to;
#define NOEX_TAINTED 8
#define NOEX_SAFE(n) ((n) >> 4) #define NOEX_SAFE(n) ((n) >> 4)
#define NOEX_WITH(n, v) ((n) | (v) << 4) #define NOEX_WITH(n, v) ((n) | (v) << 4)
#define NOEX_WITH_SAFE(n) NOEX_WITH(n, ruby_safe_level) #define NOEX_WITH_SAFE(n) NOEX_WITH(n, ruby_safe_level)
@ -1766,12 +1765,13 @@ ev_const_defined(NODE *cref, ID id, VALUE self)
while (cbase && cbase->nd_next) { while (cbase && cbase->nd_next) {
struct RClass *klass = RCLASS(cbase->nd_clss); struct RClass *klass = RCLASS(cbase->nd_clss);
if (NIL_P(klass)) return rb_const_defined(CLASS_OF(self), id); if (!NIL_P(klass)) {
if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, &result)) { if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, &result)) {
if (result == Qundef && NIL_P(rb_autoload_p((VALUE)klass, id))) { if (result == Qundef && NIL_P(rb_autoload_p((VALUE)klass, id))) {
return Qfalse; return Qfalse;
}
return Qtrue;
} }
return Qtrue;
} }
cbase = cbase->nd_next; cbase = cbase->nd_next;
} }
@ -1787,13 +1787,15 @@ ev_const_get(NODE *cref, ID id, VALUE self)
while (cbase && cbase->nd_next) { while (cbase && cbase->nd_next) {
VALUE klass = cbase->nd_clss; VALUE klass = cbase->nd_clss;
if (NIL_P(klass)) return rb_const_get(CLASS_OF(self), id); if (!NIL_P(klass)) {
while (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, &result)) { while (RCLASS(klass)->iv_tbl &&
if (result == Qundef) { st_lookup(RCLASS(klass)->iv_tbl, id, &result)) {
if (!RTEST(rb_autoload_load(klass, id))) break; if (result == Qundef) {
continue; if (!RTEST(rb_autoload_load(klass, id))) break;
continue;
}
return result;
} }
return result;
} }
cbase = cbase->nd_next; cbase = cbase->nd_next;
} }
@ -8038,11 +8040,11 @@ bind_eval(int argc, VALUE *argv, VALUE bind)
#define PROC_TSHIFT (FL_USHIFT+1) #define PROC_TSHIFT (FL_USHIFT+1)
#define PROC_TMASK (FL_USER1|FL_USER2|FL_USER3) #define PROC_TMASK (FL_USER1|FL_USER2|FL_USER3)
#define PROC_TMAX (PROC_TMASK >> PROC_TSHIFT) #define PROC_TMAX (PROC_TMASK >> PROC_TSHIFT)
#define PROC_NOSAFE FL_USER4 #define PROC_SAFE_SAVED FL_USER4
#define SAFE_LEVEL_MAX PROC_TMASK #define SAFE_LEVEL_MAX PROC_TMASK
#define proc_safe_level_p(data) (!(RBASIC(data)->flags & PROC_NOSAFE)) #define proc_safe_level_p(data) (RBASIC(data)->flags & PROC_SAFE_SAVED)
static void static void
proc_save_safe_level(VALUE data) proc_save_safe_level(VALUE data)
@ -8050,6 +8052,7 @@ proc_save_safe_level(VALUE data)
int safe = ruby_safe_level; int safe = ruby_safe_level;
if (safe > PROC_TMAX) safe = PROC_TMAX; if (safe > PROC_TMAX) safe = PROC_TMAX;
FL_SET(data, (safe << PROC_TSHIFT) & PROC_TMASK); FL_SET(data, (safe << PROC_TSHIFT) & PROC_TMASK);
FL_SET(data, PROC_SAFE_SAVED);
} }
static int static int
@ -8887,7 +8890,7 @@ rb_method_call(int argc, VALUE *argv, VALUE method)
rb_raise(rb_eTypeError, "can't call unbound method; bind first"); rb_raise(rb_eTypeError, "can't call unbound method; bind first");
} }
if (OBJ_TAINTED(method)) { if (OBJ_TAINTED(method)) {
safe = NOEX_WITH(data->safe_level, 4)|NOEX_TAINTED; safe = NOEX_WITH(data->safe_level, 4);
} }
else { else {
safe = data->safe_level; safe = data->safe_level;
@ -9328,7 +9331,7 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
struct BLOCK *block; struct BLOCK *block;
body = proc_clone(body); body = proc_clone(body);
RBASIC(body)->flags |= PROC_NOSAFE; proc_save_safe_level(body);
Data_Get_Struct(body, struct BLOCK, block); Data_Get_Struct(body, struct BLOCK, block);
block->frame.callee = id; block->frame.callee = id;
block->frame.this_func = id; block->frame.this_func = id;

View File

@ -67,7 +67,7 @@ typedef uint8_t sha2_byte; /* Exactly 1 byte */
typedef uint32_t sha2_word32; /* Exactly 4 bytes */ typedef uint32_t sha2_word32; /* Exactly 4 bytes */
typedef uint64_t sha2_word64; /* Exactly 8 bytes */ typedef uint64_t sha2_word64; /* Exactly 8 bytes */
#if defined(__GNUC__) || defined(_HPUX_SOURCE) #if defined(__GNUC__) || defined(_HPUX_SOURCE) || defined(__IBMC__)
#define ULL(number) number##ULL #define ULL(number) number##ULL
#else #else
#define ULL(number) (uint64_t)(number) #define ULL(number) (uint64_t)(number)

View File

@ -115,14 +115,15 @@ rb_syck_compile(self, port)
oid = syck_parse( parser ); oid = syck_parse( parser );
syck_lookup_sym( parser, oid, (char **)&sav ); syck_lookup_sym( parser, oid, (char **)&sav );
ret = S_ALLOC_N( char, strlen( sav->buffer ) + 3 ); bc = rb_str_new(0, strlen( sav->buffer ) + 3);
ret = RSTRING(bc)->ptr;
ret[0] = '\0'; ret[0] = '\0';
strcat( ret, "D\n" ); strcat( ret, "D\n" );
strcat( ret, sav->buffer ); strcat( ret, sav->buffer );
syck_free_parser( parser ); syck_free_parser( parser );
bc = rb_str_new2( ret ); S_FREE( ret ); rb_str_resize( bc, strlen(ret) );
if ( taint ) OBJ_TAINT( bc ); if ( taint ) OBJ_TAINT( bc );
return bc; return bc;
} }
@ -1042,13 +1043,13 @@ syck_set_ivars( vars, obj )
{ {
VALUE ivname = rb_ary_entry( vars, 0 ); VALUE ivname = rb_ary_entry( vars, 0 );
char *ivn; char *ivn;
ID ivns;
StringValue( ivname ); StringValue( ivname );
ivn = S_ALLOC_N( char, RSTRING(ivname)->len + 2 ); ivn = S_ALLOC_N( char, RSTRING(ivname)->len + 2 );
ivn[0] = '@'; snprintf(ivn, RSTRING(ivname)->len + 1, "@%s", RSTRING(ivname)->ptr);
ivn[1] = '\0'; ivns = rb_intern(ivn);
strncat( ivn, RSTRING(ivname)->ptr, RSTRING(ivname)->len );
rb_iv_set( obj, ivn, rb_ary_entry( vars, 1 ) );
S_FREE( ivn ); S_FREE( ivn );
rb_ivar_set( obj, ivns, rb_ary_entry( vars, 1 ) );
return Qnil; return Qnil;
} }

View File

@ -993,22 +993,9 @@ class CGI
loop do loop do
head = nil head = nil
if 10240 < content_length body = MorphingBody.new
require "tempfile"
body = Tempfile.new("CGI")
else
begin
require "stringio"
body = StringIO.new
rescue LoadError
require "tempfile"
body = Tempfile.new("CGI")
end
end
body.binmode if defined? body.binmode
until head and /#{boundary}(?:#{EOL}|--)/n.match(buf) until head and /#{boundary}(?:#{EOL}|--)/n.match(buf)
if (not head) and /#{EOL}#{EOL}/n.match(buf) if (not head) and /#{EOL}#{EOL}/n.match(buf)
buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do
head = $1.dup head = $1.dup
@ -1042,6 +1029,7 @@ class CGI
"" ""
end end
p body
body.rewind body.rewind
/Content-Disposition:.* filename="?([^\";]*)"?/ni.match(head) /Content-Disposition:.* filename="?([^\";]*)"?/ni.match(head)
@ -1062,7 +1050,7 @@ class CGI
end end
/Content-Disposition:.* name="?([^\";]*)"?/ni.match(head) /Content-Disposition:.* name="?([^\";]*)"?/ni.match(head)
name = $1.dup name = ($1 || "").dup
if params.has_key?(name) if params.has_key?(name)
params[name].push(body) params[name].push(body)
@ -1102,6 +1090,59 @@ class CGI
end end
private :read_from_cmdline private :read_from_cmdline
# A wrapper class to use a StringIO object as the body and switch
# to a TempFile when the passed threshold is passed.
class MorphingBody
begin
require "stringio"
@@small_buffer = lambda{StringIO.new}
rescue LoadError
require "tempfile"
@@small_buffer = lambda{
n = Tempfile.new("CGI")
n.binmode
n
}
end
def initialize(morph_threshold = 10240)
@threshold = morph_threshold
@body = @@small_buffer.call
@cur_size = 0
@morph_check = true
end
def print(data)
if @morph_check && (@cur_size + data.size > @threshold)
convert_body
end
@body.print data
end
def rewind
@body.rewind
end
def path
@body.path
end
# returns the true body object.
def extract
@body
end
private
def convert_body
new_body = TempFile.new("CGI")
new_body.binmode if defined? @body.binmode
new_body.binmode if defined? new_body.binmode
@body.rewind
new_body.print @body.read
@body = new_body
@morph_check = false
end
end
# Initialize the data from the query. # Initialize the data from the query.
# #
# Handles multipart forms (in particular, forms that involve file uploads). # Handles multipart forms (in particular, forms that involve file uploads).

View File

@ -121,61 +121,93 @@ class Delegator
undef_method m undef_method m
end end
# module MethodDelegation
# Pass in the _obj_ to delegate method calls to. All methods supported by #
# _obj_ will be delegated to. # Pass in the _obj_ to delegate method calls to. All methods supported by
# # _obj_ will be delegated to.
def initialize(obj) #
__setobj__(obj) def initialize(obj)
end __setobj__(obj)
end
# Handles the magic of delegation through \_\_getobj\_\_. # Handles the magic of delegation through \_\_getobj\_\_.
def method_missing(m, *args) def method_missing(m, *args, &block)
begin begin
target = self.__getobj__ target = self.__getobj__
unless target.respond_to?(m) unless target.respond_to?(m)
super(m, *args) super(m, *args, &block)
else
target.__send__(m, *args, &block)
end
rescue Exception
$@.delete_if{|s| /^#{__FILE__}:\d+:in `method_missing'$/ =~ s} #`
::Kernel::raise
end end
target.__send__(m, *args) end
rescue Exception
$@.delete_if{|s| /^#{__FILE__}:\d+:in `method_missing'$/ =~ s} #` #
::Kernel::raise # Checks for a method provided by this the delegate object by fowarding the
# call through \_\_getobj\_\_.
#
def respond_to?(m)
return true if super
return self.__getobj__.respond_to?(m)
end
#
# Returns true if two objects are considered same.
#
def ==(obj)
return true if obj.equal?(self)
self.__getobj__ == obj
end
#
# Returns true only if two objects are identical.
#
def equal?(obj)
self.object_id == obj.object_id
end
#
# This method must be overridden by subclasses and should return the object
# method calls are being delegated to.
#
def __getobj__
raise NotImplementedError, "need to define `__getobj__'"
end
#
# This method must be overridden by subclasses and change the object delegate
# to _obj_.
#
def __setobj__(obj)
raise NotImplementedError, "need to define `__setobj__'"
end
# Serialization support for the object returned by \_\_getobj\_\_.
def marshal_dump
__getobj__
end
# Reinitializes delegation from a serialized object.
def marshal_load(obj)
__setobj__(obj)
end
# Clone support for the object returned by \_\_getobj\_\_.
def clone
new = super
new.__setobj__(__getobj__.clone)
new
end
# Duplication support for the object returned by \_\_getobj\_\_.
def dup
new = super
new.__setobj__(__getobj__.dup)
new
end end
end end
include MethodDelegation
#
# Checks for a method provided by this the delegate object by fowarding the
# call through \_\_getobj\_\_.
#
def respond_to?(m)
return true if super
return self.__getobj__.respond_to?(m)
end
#
# This method must be overridden by subclasses and should return the object
# method calls are being delegated to.
#
def __getobj__
raise NotImplementedError, "need to define `__getobj__'"
end
#
# This method must be overridden by subclasses and change the object delegate
# to _obj_.
#
def __setobj__(obj)
raise NotImplementedError, "need to define `__setobj__'"
end
# Serialization support for the object returned by \_\_getobj\_\_.
def marshal_dump
__getobj__
end
# Reinitializes delegation from a serialized object.
def marshal_load(obj)
__setobj__(obj)
end
end end
# #
@ -208,19 +240,6 @@ class SimpleDelegator<Delegator
raise ArgumentError, "cannot delegate to self" if self.equal?(obj) raise ArgumentError, "cannot delegate to self" if self.equal?(obj)
@_sd_obj = obj @_sd_obj = obj
end end
# Clone support for the object returned by \_\_getobj\_\_.
def clone
copy = super
copy.__setobj__(__getobj__.clone)
copy
end
# Duplication support for the object returned by \_\_getobj\_\_.
def dup
copy = super
copy.__setobj__(__getobj__.dup)
copy
end
end end
# :stopdoc: # :stopdoc:
@ -243,24 +262,12 @@ def DelegateClass(superclass)
klass = Class.new klass = Class.new
methods = superclass.public_instance_methods(true) methods = superclass.public_instance_methods(true)
methods -= [ methods -= [
"__id__", "object_id", "__send__", "respond_to?", "__id__", "object_id", "__send__", "respond_to?", "==", "equal?",
"initialize", "method_missing", "__getobj__", "__setobj__", "initialize", "method_missing", "__getobj__", "__setobj__",
"clone", "dup", "marshal_dump", "marshal_load", "clone", "dup", "marshal_dump", "marshal_load",
] ]
klass.module_eval { klass.module_eval {
def initialize(obj) # :nodoc: include Delegator::MethodDelegation
@_dc_obj = obj
end
def method_missing(m, *args) # :nodoc:
unless @_dc_obj.respond_to?(m)
super(m, *args)
end
@_dc_obj.__send__(m, *args)
end
def respond_to?(m) # :nodoc:
return true if super
return @_dc_obj.respond_to?(m)
end
def __getobj__ # :nodoc: def __getobj__ # :nodoc:
@_dc_obj @_dc_obj
end end
@ -268,14 +275,6 @@ def DelegateClass(superclass)
raise ArgumentError, "cannot delegate to self" if self.equal?(obj) raise ArgumentError, "cannot delegate to self" if self.equal?(obj)
@_dc_obj = obj @_dc_obj = obj
end end
def clone # :nodoc:
super
__setobj__(__getobj__.clone)
end
def dup # :nodoc:
super
__setobj__(__getobj__.dup)
end
} }
for method in methods for method in methods
begin begin
@ -309,15 +308,23 @@ if __FILE__ == $0
p ary.class p ary.class
ary.push 25 ary.push 25
p ary p ary
ary.push 42
ary.each {|x| p x}
foo = Object.new foo = Object.new
def foo.test def foo.test
25 25
end end
def foo.iter
yield self
end
def foo.error def foo.error
raise 'this is OK' raise 'this is OK'
end end
foo2 = SimpleDelegator.new(foo) foo2 = SimpleDelegator.new(foo)
p foo2
foo2.instance_eval{print "foo\n"}
p foo.test == foo2.test # => true p foo.test == foo2.test # => true
p foo2.iter{[55,true]} # => true
foo2.error # raise error! foo2.error # raise error!
end end

View File

@ -40,7 +40,7 @@
# #
unless defined? Thread unless defined? Thread
fail "Thread not available for this ruby interpreter" raise "Thread not available for this ruby interpreter"
end end
module Sync_m module Sync_m

View File

@ -9,7 +9,7 @@
# #
unless defined? Thread unless defined? Thread
fail "Thread not available for this ruby interpreter" raise "Thread not available for this ruby interpreter"
end end
unless defined? ThreadError unless defined? ThreadError

View File

@ -310,7 +310,7 @@ module YAML
# #
# Add a transfer method for a builtin type # Add a transfer method for a builtin type
# #
def YAML.add_ruby_type( type, &transfer_proc ) def YAML.add_ruby_type( type_tag, &transfer_proc )
resolver.add_type( "tag:ruby.yaml.org,2002:#{ type_tag }", transfer_proc ) resolver.add_type( "tag:ruby.yaml.org,2002:#{ type_tag }", transfer_proc )
end end

View File

@ -520,15 +520,15 @@ tmp.close
# test redo # test redo
$bad = false $bad = false
tmp = open("while_tmp", "r") tmp = open("while_tmp", "r")
while tmp.gets() while line = tmp.gets()
line = $_ lastline = line
gsub(/vt100/, 'VT100') line = line.gsub(/vt100/, 'VT100')
if $_ != line if lastline != line
$_.gsub!('VT100', 'Vt100') line.gsub!('VT100', 'Vt100')
redo redo
end end
$bad = 1 if /vt100/ =~ $_ $bad = 1 if /vt100/ =~ line
$bad = 1 if /VT100/ =~ $_ $bad = 1 if /VT100/ =~ line
end end
test_ok(tmp.eof? && !$bad) test_ok(tmp.eof? && !$bad)
tmp.close tmp.close
@ -1837,7 +1837,7 @@ for i in 1..5
end end
tmp.close tmp.close
`./miniruby -i.bak -pe 'sub(/^[0-9]+$/){$&.to_i * 5}' script_tmp` `./miniruby -i.bak -pe '$_.sub!(/^[0-9]+$/){$&.to_i * 5}' script_tmp`
done = true done = true
tmp = open("script_tmp", "r") tmp = open("script_tmp", "r")
while tmp.gets while tmp.gets

228
string.c
View File

@ -2168,84 +2168,6 @@ uscore_get(void)
return line; return line;
} }
/*
* call-seq:
* sub!(pattern, replacement) => $_ or nil
* sub!(pattern) {|...| block } => $_ or nil
*
* Equivalent to <code>$_.sub!(<i>args</i>)</code>.
*/
static VALUE
rb_f_sub_bang(int argc, VALUE *argv)
{
return rb_str_sub_bang(argc, argv, uscore_get());
}
/*
* call-seq:
* sub(pattern, replacement) => $_
* sub(pattern) { block } => $_
*
* Equivalent to <code>$_.sub(<i>args</i>)</code>, except that
* <code>$_</code> will be updated if substitution occurs.
*/
static VALUE
rb_f_sub(int argc, VALUE *argv)
{
VALUE str = rb_str_dup(uscore_get());
if (NIL_P(rb_str_sub_bang(argc, argv, str)))
return str;
rb_lastline_set(str);
return str;
}
/*
* call-seq:
* gsub!(pattern, replacement) => string or nil
* gsub!(pattern) {|...| block } => string or nil
*
* Equivalent to <code>Kernel::gsub</code>, except <code>nil</code> is
* returned if <code>$_</code> is not modified.
*
* $_ = "quick brown fox"
* gsub! /cat/, '*' #=> nil
* $_ #=> "quick brown fox"
*/
static VALUE
rb_f_gsub_bang(int argc, VALUE *argv)
{
return rb_str_gsub_bang(argc, argv, uscore_get());
}
/*
* call-seq:
* gsub(pattern, replacement) => string
* gsub(pattern) {|...| block } => string
*
* Equivalent to <code>$_.gsub...</code>, except that <code>$_</code>
* receives the modified result.
*
* $_ = "quick brown fox"
* gsub /[aeiou]/, '*' #=> "q**ck br*wn f*x"
* $_ #=> "q**ck br*wn f*x"
*/
static VALUE
rb_f_gsub(int argc, VALUE *argv)
{
VALUE str = rb_str_dup(uscore_get());
if (NIL_P(rb_str_gsub_bang(argc, argv, str)))
return str;
rb_lastline_set(str);
return str;
}
/* /*
* call-seq: * call-seq:
* str.reverse! => str * str.reverse! => str
@ -3437,20 +3359,6 @@ rb_str_split(VALUE str, const char *sep0)
return rb_str_split_m(1, &sep, str); return rb_str_split_m(1, &sep, str);
} }
/*
* call-seq:
* split([pattern [, limit]]) => array
*
* Equivalent to <code>$_.split(<i>pattern</i>, <i>limit</i>)</code>.
* See <code>String#split</code>.
*/
static VALUE
rb_f_split(int argc, VALUE *argv)
{
return rb_str_split_m(argc, argv, uscore_get());
}
/* /*
* call-seq: * call-seq:
* str.each(separator=$/) {|substr| block } => str * str.each(separator=$/) {|substr| block } => str
@ -3620,61 +3528,6 @@ rb_str_chop(VALUE str)
} }
/*
* call-seq:
* chop! => $_ or nil
*
* Equivalent to <code>$_.chop!</code>.
*
* a = "now\r\n"
* $_ = a
* chop! #=> "now"
* chop! #=> "no"
* chop! #=> "n"
* chop! #=> ""
* chop! #=> nil
* $_ #=> ""
* a #=> ""
*/
static VALUE
rb_f_chop_bang(VALUE str)
{
return rb_str_chop_bang(uscore_get());
}
/*
* call-seq:
* chop => string
*
* Equivalent to <code>($_.dup).chop!</code>, except <code>nil</code>
* is never returned. See <code>String#chop!</code>.
*
* a = "now\r\n"
* $_ = a
* chop #=> "now"
* $_ #=> "now"
* chop #=> "no"
* chop #=> "n"
* chop #=> ""
* chop #=> ""
* a #=> "now\r\n"
*/
static VALUE
rb_f_chop(void)
{
VALUE str = uscore_get();
if (RSTRING(str)->len > 0) {
str = rb_str_dup(str);
rb_str_chop_bang(str);
rb_lastline_set(str);
}
return str;
}
/* /*
* call-seq: * call-seq:
* str.chomp!(separator=$/) => str or nil * str.chomp!(separator=$/) => str or nil
@ -3780,57 +3633,6 @@ rb_str_chomp(int argc, VALUE *argv, VALUE str)
return str; return str;
} }
/*
* call-seq:
* chomp! => $_ or nil
* chomp!(string) => $_ or nil
*
* Equivalent to <code>$_.chomp!(<em>string</em>)</code>. See
* <code>String#chomp!</code>
*
* $_ = "now\n"
* chomp! #=> "now"
* $_ #=> "now"
* chomp! "x" #=> nil
* $_ #=> "now"
*/
static VALUE
rb_f_chomp_bang(int argc, VALUE *argv)
{
return rb_str_chomp_bang(argc, argv, uscore_get());
}
/*
* call-seq:
* chomp => $_
* chomp(string) => $_
*
* Equivalent to <code>$_ = $_.chomp(<em>string</em>)</code>. See
* <code>String#chomp</code>.
*
* $_ = "now\n"
* chomp #=> "now"
* $_ #=> "now"
* chomp "ow" #=> "n"
* $_ #=> "n"
* chomp "xxx" #=> "n"
* $_ #=> "n"
*/
static VALUE
rb_f_chomp(int argc, VALUE *argv)
{
VALUE str = uscore_get();
VALUE dup = rb_str_dup(str);
if (NIL_P(rb_str_chomp_bang(argc, argv, dup)))
return str;
rb_lastline_set(dup);
return dup;
}
/* /*
* call-seq: * call-seq:
* str.lstrip! => self or nil * str.lstrip! => self or nil
@ -4075,21 +3877,6 @@ rb_str_scan(VALUE str, VALUE pat)
return str; return str;
} }
/*
* call-seq:
* scan(pattern) => array
* scan(pattern) {|///| block } => $_
*
* Equivalent to calling <code>$_.scan</code>. See
* <code>String#scan</code>.
*/
static VALUE
rb_f_scan(VALUE self, VALUE pat)
{
return rb_str_scan(uscore_get(), pat);
}
/* /*
* call-seq: * call-seq:
@ -4510,21 +4297,6 @@ Init_String(void)
rb_define_method(rb_cString, "sum", rb_str_sum, -1); rb_define_method(rb_cString, "sum", rb_str_sum, -1);
rb_define_global_function("sub", rb_f_sub, -1);
rb_define_global_function("gsub", rb_f_gsub, -1);
rb_define_global_function("sub!", rb_f_sub_bang, -1);
rb_define_global_function("gsub!", rb_f_gsub_bang, -1);
rb_define_global_function("chop", rb_f_chop, 0);
rb_define_global_function("chop!", rb_f_chop_bang, 0);
rb_define_global_function("chomp", rb_f_chomp, -1);
rb_define_global_function("chomp!", rb_f_chomp_bang, -1);
rb_define_global_function("split", rb_f_split, -1);
rb_define_global_function("scan", rb_f_scan, 1);
rb_define_method(rb_cString, "slice", rb_str_aref_m, -1); rb_define_method(rb_cString, "slice", rb_str_aref_m, -1);
rb_define_method(rb_cString, "slice!", rb_str_slice_bang, -1); rb_define_method(rb_cString, "slice!", rb_str_slice_bang, -1);

View File

@ -31,7 +31,7 @@ class DRbService
@server || @@server @server || @@server
end end
def self.ext_service(name) def self.ext_service(name)
timeout(10, RuntimeError) do timeout(100, RuntimeError) do
manager.service(name) manager.service(name)
end end
end end