Project

General

Profile

Actions

Bug #4536

closed

定数参照について1.8と1.9の違い

Added by matz (Yukihiro Matsumoto) over 13 years ago. Updated over 13 years ago.

Status:
Closed
Target version:
-
ruby -v:
-
Backport:
[ruby-dev:43365]

Description

=begin
以下のプログラムは1.8ではエラーになりますが、1.9ではエラーを
示さず動作します。定数参照は(できるだけ)静的スコープで、とい
う設計方針に従えば、1.8の方が正しいと思います。

どうやって直したら良いと思いますか? あるいは直さずに今後は
1.9的挙動が正としますか?

module A
B = 42
end

A.class_eval do
def self.f
p B
end
end

A.f

=end

Updated by ko1 (Koichi Sasada) over 13 years ago

  • ruby -v changed from ruby 1.9.3dev (2011-03-29 trunk 31207) [i686-linux] to -

=begin
 ささだです.

(2011/03/29 17:41), Yukihiro Matsumoto wrote:

以下のプログラムは1.8ではエラーになりますが、1.9ではエラーを
示さず動作します。定数参照は(できるだけ)静的スコープで、とい
う設計方針に従えば、1.8の方が正しいと思います。

どうやって直したら良いと思いますか? あるいは直さずに今後は
1.9的挙動が正としますか?

module A
B = 42
end

A.class_eval do
def self.f
p B
end
end

A.f

module A; B = 42; end
A.class_eval{p B}
#=> `block in ': uninitialized constant Module::B (NameError)

なので,それが動くのはまずいかもしれませんね.少し考えさせてください.

しかし,なんで Module::B なんだ.

--
// SASADA Koichi at atdot dot net
=end

Updated by ko1 (Koichi Sasada) over 13 years ago

=begin
 ささだです.

(2011/03/29 17:41), Yukihiro Matsumoto wrote:

以下のプログラムは1.8ではエラーになりますが、1.9ではエラーを
示さず動作します。定数参照は(できるだけ)静的スコープで、とい
う設計方針に従えば、1.8の方が正しいと思います。

どうやって直したら良いと思いますか? あるいは直さずに今後は
1.9的挙動が正としますか?

module A
B = 42
end

A.class_eval do
def self.f
p B
end
end

A.f

module A; B = 42; end
A.class_eval{p B}
#=> `block in ': uninitialized constant Module::B (NameError)

なので,それが動くのはまずいかもしれませんね.少し考えさせてください.

しかし,なんで Module::B なんだ.

--
// SASADA Koichi at atdot dot net
=end

Updated by shugo (Shugo Maeda) over 13 years ago

=begin
前田です。

2011年3月29日17:55 SASADA Koichi :

module A; B = 42; end
A.class_eval{p B}
#=> `block in ': uninitialized constant Module::B (NameError)

なので,それが動くのはまずいかもしれませんね.少し考えさせてください.

以下のようにCOPY_CREFでフラグを伝搬させるとこの部分に関しては1.8と同じ動作になるようです。

diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index 979c342..31ef216 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -154,6 +154,9 @@ extern VALUE ruby_vm_const_missing_count;
(c1)->nd_clss = __tmp_c2->nd_clss;
(c1)->nd_visi = __tmp_c2->nd_visi;
(c1)->nd_next = __tmp_c2->nd_next; \

  • if (__tmp_c2->flags & NODE_FL_CREF_PUSHED_BY_EVAL) { \
  •  (c1)->flags |= NODE_FL_CREF_PUSHED_BY_EVAL; \
    
  • }
    } while (0)

#define CALL_METHOD(num, blockptr, flag, id, me, recv) do { \

あんまりちゃんと考えてないので副作用があるかも。

しかし,なんで Module::B なんだ.

こっちはまだ見てませんが、何なんでしょうね…。

--
Shugo Maeda
=end

Updated by shugo (Shugo Maeda) over 13 years ago

=begin
前田です。

2011年3月29日17:55 SASADA Koichi :

module A; B = 42; end
A.class_eval{p B}
#=> `block in ': uninitialized constant Module::B (NameError)

なので,それが動くのはまずいかもしれませんね.少し考えさせてください.

以下のようにCOPY_CREFでフラグを伝搬させるとこの部分に関しては1.8と同じ動作になるようです。

diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index 979c342..31ef216 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -154,6 +154,9 @@ extern VALUE ruby_vm_const_missing_count;
(c1)->nd_clss = __tmp_c2->nd_clss;
(c1)->nd_visi = __tmp_c2->nd_visi;
(c1)->nd_next = __tmp_c2->nd_next; \

  • if (__tmp_c2->flags & NODE_FL_CREF_PUSHED_BY_EVAL) { \
  •  (c1)->flags |= NODE_FL_CREF_PUSHED_BY_EVAL; \
    
  • }
    } while (0)

#define CALL_METHOD(num, blockptr, flag, id, me, recv) do { \

あんまりちゃんと考えてないので副作用があるかも。

しかし,なんで Module::B なんだ.

こっちはまだ見てませんが、何なんでしょうね…。

--
Shugo Maeda
=end

Updated by ko1 (Koichi Sasada) over 13 years ago

=begin
 ささだです.

(2011/03/29 18:37), Shugo Maeda wrote:

以下のようにCOPY_CREFでフラグを伝搬させるとこの部分に関しては1.8と同じ動作になるようです。

diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index 979c342..31ef216 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -154,6 +154,9 @@ extern VALUE ruby_vm_const_missing_count;
(c1)->nd_clss = __tmp_c2->nd_clss;
(c1)->nd_visi = __tmp_c2->nd_visi;
(c1)->nd_next = __tmp_c2->nd_next; \

  • if (__tmp_c2->flags & NODE_FL_CREF_PUSHED_BY_EVAL) { \
  •  (c1)->flags |= NODE_FL_CREF_PUSHED_BY_EVAL; \
    
  • }
    } while (0)

#define CALL_METHOD(num, blockptr, flag, id, me, recv) do { \

あんまりちゃんと考えてないので副作用があるかも。

 おお,知らないところだ :) テストが通るのならいいんでないでしょうか.

--
// SASADA Koichi at atdot dot net
=end

Updated by ko1 (Koichi Sasada) over 13 years ago

=begin
 ささだです.

(2011/03/29 18:37), Shugo Maeda wrote:

以下のようにCOPY_CREFでフラグを伝搬させるとこの部分に関しては1.8と同じ動作になるようです。

diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index 979c342..31ef216 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -154,6 +154,9 @@ extern VALUE ruby_vm_const_missing_count;
(c1)->nd_clss = __tmp_c2->nd_clss;
(c1)->nd_visi = __tmp_c2->nd_visi;
(c1)->nd_next = __tmp_c2->nd_next; \

  • if (__tmp_c2->flags & NODE_FL_CREF_PUSHED_BY_EVAL) { \
  •  (c1)->flags |= NODE_FL_CREF_PUSHED_BY_EVAL; \
    
  • }
    } while (0)

#define CALL_METHOD(num, blockptr, flag, id, me, recv) do { \

あんまりちゃんと考えてないので副作用があるかも。

 おお,知らないところだ :) テストが通るのならいいんでないでしょうか.

--
// SASADA Koichi at atdot dot net
=end

Updated by matz (Yukihiro Matsumoto) over 13 years ago

=begin
まつもと ゆきひろです

テストでエラーが増えないようならコミットしていただけませんか?

In message "Re: [ruby-dev:43367] Re: [Ruby 1.9 - Bug #4536][Open] 定数参照について1.8と1.9の違い"
on Tue, 29 Mar 2011 18:37:47 +0900, Shugo Maeda writes:
|
|前田です。
|
|2011年3月29日17:55 SASADA Koichi :
|> module A; B = 42; end
|> A.class_eval{p B}
|> #=> `block in ': uninitialized constant Module::B (NameError)
|>
|> なので,それが動くのはまずいかもしれませんね.少し考えさせてください.
|
|以下のようにCOPY_CREFでフラグを伝搬させるとこの部分に関しては1.8と同じ動作になるようです。
|
|diff --git a/vm_insnhelper.h b/vm_insnhelper.h
|index 979c342..31ef216 100644
|--- a/vm_insnhelper.h
|+++ b/vm_insnhelper.h
|@@ -154,6 +154,9 @@ extern VALUE ruby_vm_const_missing_count;
| (c1)->nd_clss = __tmp_c2->nd_clss;
| (c1)->nd_visi = __tmp_c2->nd_visi;
| (c1)->nd_next = __tmp_c2->nd_next;
|+ if (__tmp_c2->flags & NODE_FL_CREF_PUSHED_BY_EVAL) {
|+ (c1)->flags |= NODE_FL_CREF_PUSHED_BY_EVAL;
|+ }
| } while (0)
|
| #define CALL_METHOD(num, blockptr, flag, id, me, recv) do {
|
|あんまりちゃんと考えてないので副作用があるかも。
|
|> # しかし,なんで Module::B なんだ.
|
|こっちはまだ見てませんが、何なんでしょうね…。
|
|--
|Shugo Maeda
=end

Updated by matz (Yukihiro Matsumoto) over 13 years ago

=begin
まつもと ゆきひろです

テストでエラーが増えないようならコミットしていただけませんか?

In message "Re: [ruby-dev:43367] Re: [Ruby 1.9 - Bug #4536][Open] 定数参照について1.8と1.9の違い"
on Tue, 29 Mar 2011 18:37:47 +0900, Shugo Maeda writes:
|
|前田です。
|
|2011年3月29日17:55 SASADA Koichi :
|> module A; B = 42; end
|> A.class_eval{p B}
|> #=> `block in ': uninitialized constant Module::B (NameError)
|>
|> なので,それが動くのはまずいかもしれませんね.少し考えさせてください.
|
|以下のようにCOPY_CREFでフラグを伝搬させるとこの部分に関しては1.8と同じ動作になるようです。
|
|diff --git a/vm_insnhelper.h b/vm_insnhelper.h
|index 979c342..31ef216 100644
|--- a/vm_insnhelper.h
|+++ b/vm_insnhelper.h
|@@ -154,6 +154,9 @@ extern VALUE ruby_vm_const_missing_count;
| (c1)->nd_clss = __tmp_c2->nd_clss;
| (c1)->nd_visi = __tmp_c2->nd_visi;
| (c1)->nd_next = __tmp_c2->nd_next;
|+ if (__tmp_c2->flags & NODE_FL_CREF_PUSHED_BY_EVAL) {
|+ (c1)->flags |= NODE_FL_CREF_PUSHED_BY_EVAL;
|+ }
| } while (0)
|
| #define CALL_METHOD(num, blockptr, flag, id, me, recv) do {
|
|あんまりちゃんと考えてないので副作用があるかも。
|
|> # しかし,なんで Module::B なんだ.
|
|こっちはまだ見てませんが、何なんでしょうね…。
|
|--
|Shugo Maeda
=end

Updated by shugo (Shugo Maeda) over 13 years ago

=begin
前田です。

2011年3月30日8:28 Yukihiro Matsumoto :

テストでエラーが増えないようならコミットしていただけませんか?

test/ruby/test_defined.rbが失敗するようになりましたが、このバグに依存した
テストだったのでclass_evalを使わないように修正してcommitしました。

--
Shugo Maeda
=end

Updated by shugo (Shugo Maeda) over 13 years ago

=begin
前田です。

2011年3月30日8:28 Yukihiro Matsumoto :

テストでエラーが増えないようならコミットしていただけませんか?

test/ruby/test_defined.rbが失敗するようになりましたが、このバグに依存した
テストだったのでclass_evalを使わないように修正してcommitしました。

--
Shugo Maeda
=end

Updated by shugo (Shugo Maeda) over 13 years ago

=begin
前田です。

2011年3月29日18:37 Shugo Maeda :

しかし,なんで Module::B なんだ.

こっちはまだ見てませんが、何なんでしょうね…。

vm_get_ev_const()の中でroot_crefが正しく設定されないケースが
あったせいのようです。
修正したところ、test_eval.rbの以下のテストが失敗するようになりましたが、
テストの方を修正してcommit (r31221)しました。

assert_equal %q{C}, %q{
Const = :top
class C
Const = :Cq
end
C.class_eval{
def m
Const
end
}
C.new.m
}

--
Shugo Maeda
=end

Updated by shugo (Shugo Maeda) over 13 years ago

=begin
前田です。

2011年3月29日18:37 Shugo Maeda :

しかし,なんで Module::B なんだ.

こっちはまだ見てませんが、何なんでしょうね…。

vm_get_ev_const()の中でroot_crefが正しく設定されないケースが
あったせいのようです。
修正したところ、test_eval.rbの以下のテストが失敗するようになりましたが、
テストの方を修正してcommit (r31221)しました。

assert_equal %q{C}, %q{
Const = :top
class C
Const = :Cq
end
C.class_eval{
def m
Const
end
}
C.new.m
}

--
Shugo Maeda
=end

Updated by ko1 (Koichi Sasada) over 13 years ago

  • Status changed from Open to Feedback
  • Assignee set to shugo (Shugo Maeda)

これは閉じてもいいでしょうか.

Updated by shugo (Shugo Maeda) over 13 years ago

  • Assignee changed from shugo (Shugo Maeda) to matz (Yukihiro Matsumoto)

Koichi Sasada wrote:

これは閉じてもいいでしょうか.

まつともさんがこれでいいならいいと思います。
というわけでまつもとさんにアサインしました。

Actions #15

Updated by matz (Yukihiro Matsumoto) over 13 years ago

  • Status changed from Feedback to Closed
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0