[#34556] /(.)(.)/.match("ab").select {|v| true } is empty — Tanaka Akira <akr@...>
以下のように、MatchData#select でブロックが常に真なのに結果
[#34567] write to broken pipe on Linux — Nobuyoshi Nakada <nobu@...>
なかだです。
まつもと ゆきひろです
なかだです。
[#34571] Re: [ruby-cvs:23495] Ruby:r16255 (ruby_1_8, trunk): * range.c (range_step): allow float step bigger than zero but less — Tanaka Akira <akr@...>
In article <200805011435.m41EZFBL003014@ci.ruby-lang.org>,
[#34605] Array#mapがEnumeratorを返さない — rubikitch@...
るびきちです。
[#34623] Marshal.load( Marshal.dump( Float ) )の不一致@1.8 — "H.Holon" <holon@...>
H.Holonです。
[#34646] break in lambda — Tanaka Akira <akr@...>
lambda 直下に break があったとき、なにごともなかったかのよう
[#34647] fork 不可能な環境での test_argv0_noarg — wanabe <s.wanabe@...>
ワナベと申します。
まつもと ゆきひろです
こんにちは、なかむら(う)です。
まつもと ゆきひろです
こんにちは、なかむら(う)です。
須藤です。
[#34648] Bignum のメソッドからの bigzero_p — wanabe <s.wanabe@...>
ワナベと申します。
[#34676] removing Array#nitems {} — "Akinori MUSHA" <knu@...>
Array#nitems はnilでない要素を数えるメソッドですが、ブロックを
[#34691] ext/openssl and newer OpenSSL — Takahiro Kambe <taca@...>
こんにちは。
[#34692] [ruby1.9] fork と thread — Hidetoshi NAGAI <nagai@...>
永井@知能.九工大です.
[#34726] memory leak by Array#sort! — Tanaka Akira <akr@...>
以下のように、Array#sort! の中で配列を変更するとメモりリークします。
[#34739] net/imap uses Thread#raise — Tanaka Akira <akr@...>
net/imap が原因だと思うのですが、
前田です。
In article <704d5db90805210204o7aa80c00lfeb13a34230c2c03@mail.gmail.com>,
なかだです。
[#34741] Date.parse("##-##-##") — "Akinori MUSHA" <knu@...>
Date.parse("##.##.##") の ruby_1_8 における挙動が trunk とも
> Date.parse("##.##.##") の ruby_1_8 における挙動が trunk とも
[#34742] Ruby 1.8.7-preview3 has been released — "Akinori MUSHA" <knu@...>
Ruby 1.8.7-preview3 をリリースしました。
お疲れ様です。
At Mon, 19 May 2008 11:28:10 +0900,
In message <86k5hrow30.knu@iDaemons.org>
もう一つ追加です。
At Mon, 19 May 2008 18:55:42 +0900,
[#34751] benchmark result of reverse_complement — SASADA Koichi <ko1@...>
ささだです.
[#34758] Re: [ruby-cvs:23717] Ruby:r16477 (trunk): * regparse.c (PINC): use optimized enclen() instead of — SASADA Koichi <ko1@...>
ささだです.
遠藤と申します。
[#34768] Improvement of lazy sweep patch — authorNari <authornari@...>
authorNariです。
まつもと ゆきひろです
[#34775] (1..5).step(SimpleDelegator.new(1.5)) {|x| p x} differ from (1..5).step(1.5) {|x| p x} — Tanaka Akira <akr@...>
以下のように (1..5).step(1.5) {|x| p x} と
[#34800] Windows2000上でtrunkがビルドできない — KIMURA Koichi <kimura.koichi@...>
木村です。
こんにちは、なかむら(う)です。
木村です。
木村です。
こんにちは、なかむら(う)です。
木村です。
こんにちは、なかむら(う)です。
[#34810] -Wall — SASADA Koichi <ko1@...>
ささだです.
[#34830] return value of pp — "Yusuke ENDOH" <mame@...>
遠藤です。
[#34877] [Ruby 1.9 - Bug #11] prelude.c compilation problem on mswin32 — redmine@...
Issue #11 has been updated by Usaku NAKAMURA.
[#34883] [#19002] RUBY_* constants — Kazuhiro NISHIYAMA <zn@...>
西山和広です。
[#34889] Ruby 1.8.7-preview4 test-all failed in OpenSSL::TestSSL — Nobuhiro IMAI <nov@...>
いまいです。
Nobuhiro IMAI さんは書きました:
At Sat, 31 May 2008 21:06:47 +0900,
この話題についていろいろ試していて気付いたのですが
[ruby-dev:34707] Re: fork 不可能な環境での test_argv0_noarg
In article <87ve1hmde3.fsf@fsij.org>,
Tanaka Akira <akr@fsij.org> writes:
> 実行すると NotImplementedError になり、respond_to? で調べる
> と偽になる特殊なメソッドを導入するのはどうですかね。
>
> undef みたいなかんじで。
実装するとこんな感じでしょうか。
個々のメソッドについてはとりあえず fork と File.lchmod だけ
対処してあります。
GNU/Linux には lchmod がないので、File.respond_to?(:lchmod)
は false になり、File.lchmod を呼び出すと
NotImplementedError になります。
% ./ruby -ve '
p File.respond_to?(:lchmod)
File.lchmod("foo", 0777)'
ruby 1.9.0 (2008-05-14 revision 16419) [i686-linux]
false
-e:3:in `lchmod': lchmod() function is unimplemented on this machine (NotImplementedError)
from -e:3:in `<main>'
Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h (revision 16419)
+++ include/ruby/intern.h (working copy)
@@ -252,6 +252,7 @@ int rb_method_boundp(VALUE, ID, int);
VALUE rb_eval_cmd(VALUE, VALUE, int);
int rb_obj_respond_to(VALUE, ID, int);
int rb_respond_to(VALUE, ID);
+void rb_define_notimplement_method_id(VALUE mod, ID id, int noex);
void rb_interrupt(void);
VALUE rb_apply(VALUE, ID, VALUE);
void rb_backtrace(void);
Index: include/ruby/node.h
===================================================================
--- include/ruby/node.h (revision 16419)
+++ include/ruby/node.h (working copy)
@@ -498,6 +498,8 @@ NODE *rb_node_newnode(enum node_type,VAL
NODE* rb_method_node(VALUE klass, ID id);
int rb_node_arity(NODE* node);
+int rb_notimplement_body_p(NODE*);
+
struct global_entry *rb_global_entry(ID);
VALUE rb_gvar_get(struct global_entry *);
VALUE rb_gvar_set(struct global_entry *, VALUE);
Index: proc.c
===================================================================
--- proc.c (revision 16419)
+++ proc.c (working copy)
@@ -935,6 +935,15 @@ method_owner(VALUE obj)
return data->oclass;
}
+static VALUE
+method_notimplemented_p(VALUE obj)
+{
+ struct METHOD *data;
+
+ Data_Get_Struct(obj, struct METHOD, data);
+ return rb_notimplement_body_p(data->body) ? Qtrue : Qfalse;
+}
+
/*
* call-seq:
* obj.method(sym) => method
@@ -1763,6 +1772,7 @@ Init_Proc(void)
rb_define_method(rb_cMethod, "name", method_name, 0);
rb_define_method(rb_cMethod, "owner", method_owner, 0);
rb_define_method(rb_cMethod, "unbind", method_unbind, 0);
+ rb_define_method(rb_cMethod, "notimplemented?", method_notimplemented_p, 0);
rb_define_method(rb_mKernel, "method", rb_obj_method, 1);
rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1);
@@ -1780,6 +1790,7 @@ Init_Proc(void)
rb_define_method(rb_cUnboundMethod, "name", method_name, 0);
rb_define_method(rb_cUnboundMethod, "owner", method_owner, 0);
rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
+ rb_define_method(rb_cUnboundMethod, "notimplemented?", method_notimplemented_p, 0);
/* Module#*_method */
rb_define_method(rb_cModule, "instance_method", rb_mod_instance_method, 1);
Index: class.c
===================================================================
--- class.c (revision 16419)
+++ class.c (working copy)
@@ -759,25 +759,40 @@ rb_obj_singleton_methods(int argc, VALUE
void
rb_define_method_id(VALUE klass, ID name, VALUE (*func)(ANYARGS), int argc)
{
- rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC);
+ if (func)
+ rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC);
+ else
+ rb_define_notimplement_method_id(klass, name, NOEX_PUBLIC);
}
void
rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
{
- rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PUBLIC);
+ ID id = rb_intern(name);
+ if (func)
+ rb_add_method(klass, id, NEW_CFUNC(func, argc), NOEX_PUBLIC);
+ else
+ rb_define_notimplement_method_id(klass, id, NOEX_PUBLIC);
}
void
rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
{
- rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PROTECTED);
+ ID id = rb_intern(name);
+ if (func)
+ rb_add_method(klass, id, NEW_CFUNC(func, argc), NOEX_PROTECTED);
+ else
+ rb_define_notimplement_method_id(klass, id, NOEX_PROTECTED);
}
void
rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
{
- rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PRIVATE);
+ ID id = rb_intern(name);
+ if (func)
+ rb_add_method(klass, id, NEW_CFUNC(func, argc), NOEX_PRIVATE);
+ else
+ rb_define_notimplement_method_id(klass, id, NOEX_PRIVATE);
}
void
Index: process.c
===================================================================
--- process.c (revision 16419)
+++ process.c (working copy)
@@ -2394,10 +2394,10 @@ rb_fork(int *status, int (*chfunc)(void*
* fork doesn't copy other threads.
*/
+#if defined(HAVE_FORK) && !defined(__NetBSD__)
static VALUE
rb_f_fork(VALUE obj)
{
-#if defined(HAVE_FORK) && !defined(__NetBSD__)
rb_pid_t pid;
rb_secure(2);
@@ -2423,11 +2423,10 @@ rb_f_fork(VALUE obj)
default:
return PIDT2NUM(pid);
}
+}
#else
- rb_notimplement();
+#define rb_f_fork 0
#endif
-}
-
/*
* call-seq:
Index: eval_method.c
===================================================================
--- eval_method.c (revision 16419)
+++ eval_method.c (working copy)
@@ -18,6 +18,8 @@ struct cache_entry { /* method hash tab
static struct cache_entry cache[CACHE_SIZE];
static int ruby_running = 0;
+static NODE *notimplement_body = 0;
+
void
rb_clear_cache(void)
{
@@ -403,6 +405,12 @@ rb_export_method(VALUE klass, ID name, I
}
int
+rb_notimplement_body_p(NODE *method)
+{
+ return method == notimplement_body ? Qtrue : Qfalse;
+}
+
+int
rb_method_boundp(VALUE klass, ID id, int ex)
{
NODE *method;
@@ -411,6 +419,8 @@ rb_method_boundp(VALUE klass, ID id, int
if (ex && (method->nd_noex & NOEX_PRIVATE)) {
return Qfalse;
}
+ if (rb_notimplement_body_p(method->nd_body))
+ return Qfalse;
return Qtrue;
}
return Qfalse;
@@ -645,10 +655,49 @@ rb_mod_alias_method(VALUE mod, VALUE new
return mod;
}
+static VALUE
+notimplement_cfunc(VALUE obj)
+{
+ rb_notimplement();
+}
+
+void
+rb_define_notimplement_method_id(VALUE mod, ID id, int noex)
+{
+ rb_add_method(mod, id, notimplement_body, noex);
+}
+
+static VALUE
+rb_mod_notimplemented_method(int argc, VALUE *argv, VALUE mod)
+{
+ int i;
+ if (ruby_cbase() == rb_cObject && mod == rb_cObject) {
+ rb_secure(4);
+ }
+
+ for (i = 0; i < argc; i++) {
+ ID id = rb_to_id(argv[i]);
+
+ if (rb_safe_level() >= 4 && !OBJ_TAINTED(mod)) {
+ rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'",
+ rb_id2name(id));
+ }
+ rb_frozen_class_p(mod);
+ if (id == object_id || id == __send__ || id == init) {
+ rb_warn("notimplementing `%s' may cause serious problem", rb_id2name(id));
+ }
+ rb_define_notimplement_method_id(mod, id, NOEX_PUBLIC);
+ }
+ return mod;
+}
+
static void
Init_eval_method(void)
{
rb_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, -1);
rb_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, -1);
rb_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2);
+ rb_global_variable(¬implement_body);
+ notimplement_body = NEW_CFUNC(notimplement_cfunc, -1);
+ rb_define_private_method(rb_cModule, "notimplemented_method", rb_mod_notimplemented_method, -1);
}
Index: file.c
===================================================================
--- file.c (revision 16419)
+++ file.c (working copy)
@@ -1901,12 +1901,7 @@ rb_file_s_lchmod(int argc, VALUE *argv)
return LONG2FIX(n);
}
#else
-static VALUE
-rb_file_s_lchmod(int argc, VALUE *argv)
-{
- rb_notimplement();
- return Qnil; /* not reached */
-}
+#define rb_file_s_lchmod 0
#endif
struct chown_args {
Index: test/ruby/test_notimp.rb
===================================================================
--- test/ruby/test_notimp.rb (revision 0)
+++ test/ruby/test_notimp.rb (revision 0)
@@ -0,0 +1,33 @@
+require 'test/unit'
+
+class TestNotImplement < Test::Unit::TestCase
+ class C
+ notimplemented_method :n
+ def x() end
+ end
+
+ def test_respond_to
+ assert_equal(false, C.new.respond_to?(:n))
+ assert_equal(true, C.new.respond_to?(:x))
+ end
+
+ def test_call
+ assert_raise(NotImplementedError) { C.new.n }
+ assert_nothing_raised { C.new.x }
+ end
+
+ def test_method
+ m = C.new.method(:n)
+ assert(m.notimplemented?)
+ m = C.new.method(:x)
+ assert(!m.notimplemented?)
+ end
+
+ def test_umethod
+ m = C.instance_method(:n)
+ assert(m.notimplemented?)
+ m = C.instance_method(:x)
+ assert(!m.notimplemented?)
+ end
+
+end
--
[田中 哲][たなか あきら][Tanaka Akira]