Feature #3328

Kernel#p outputs as default_internal encoding, and so on

Added by Masaya Tarui almost 4 years ago. Updated over 1 year ago.

[ruby-dev:41382]
Status:Assigned
Priority:Normal
Assignee:Masaya Tarui
Category:core
Target version:next minor

Description

=begin
樽家です。

Feature #2102 でString#inspectについては強制的にencodingを揃えるようになりましたが、SymbolやRegexpについてはそうなっておらず、同じような簡単にエラーになる状態になっています。ユーザー定義のinspectにも同様です。またにinspectで文字コードの違いが区別できません。

そこで、Kernel#pで表示する前やArrayやHashで各inspect結果をマージする前に、String#inspectと同様な処理を行うのはどうでしょうか?具体的にはinspectで想定するEncodingと異なる場合に、非ASCII文字をエスケープ表示にするString#inspectencodeを追加し、それをrbinspectから呼ぶ事を提案したいと思います。ASCII文字については手を加えないため、不可逆ですが実用上は問題ないと思います。
ご検討をお願いします。

以下に現状と提案後の結果、Kernel#pの定義の変更を示します。
またこの変更を行うpatchを添付します。

cat inspect.rb
# -- encoding: utf-8 --
Encoding.defaultexternal = "WINDOWS-31J"
STDOUT.set
encoding "WINDOWS-31J"
a = "あ"
su = a.intern
se = a.encode("euc-jp").intern
sw = a.encode("windows-31j").intern
ru= /#{a}/
re= /#{a.encode("euc-jp")}/
rw= /#{a.encode("windows-31j")}/
hash = { su => se }
p su,se,sw,ru,re,rw
p hash rescue p $!
p [ru,re,rw,su,se,sw] rescue p $!

ruby_org inspect.rb
:あ
:あ
:あ
/あ/
/あ/
/あ/
#
#

ruby_new inspect.rb
:\u3042
:\x{A4A2}
:あ
/\u3042/
/\x{A4A2}/
/あ/
{:\u3042=>:\x{A4A2}}
[/\u3042/, /\x{A4A2}/, /あ/, :\u3042, :\x{A4A2}, :あ]

また、
Encoding.defaultexternal = "WINDOWS-31J"
STDOUT.set
encoding "WINDOWS-31J"
class A ;def inspect ; "あ".encode("euc-jp") end ; end
p A.new
puts A.new.inspect
puts A.new.inspect.inspect_encode
の結果が
\x{A4A2}

\x{A4A2}
となり、pの定義が少し変わります。
=end

patch Magnifier - Kernel#pほか変更パッチ (4.68 KB) Masaya Tarui, 05/21/2010 08:10 AM

History

#1 Updated by Yui NARUSE almost 4 years ago

=begin
成瀬です。

(2010/05/21 8:10), Masaya Tarui wrote:

Feature #2102 でString#inspectについては強制的にencodingを
揃えるようになりましたが、SymbolやRegexpについてはそうなっておらず、
同じような簡単にエラーになる状態になっています。ユーザー定義のinspectにも
同様です。またにinspectで文字コードの違いが区別できません。

Symbol と Regexp は忘れていました。
確かに対処が必要だと思います。

そこで、Kernel#pで表示する前やArrayやHashで各inspect結果をマージする前に、
String#inspectと同様な処理を行うのはどうでしょうか?具体的にはinspectで
想定するEncodingと異なる場合に、非ASCII文字をエスケープ表示にする
String#inspectencodeを追加し、それをrbinspectから呼ぶ事を提案したいと
思います。ASCII文字については手を加えないため、不可逆ですが実用上は問題
ないと思います。 ご検討をお願いします。

同様な処理といいながらなぜ新しい API を追加するんですか。

--
NARUSE, Yui naruse@airemix.jp

=end

#2 Updated by Masaya Tarui almost 4 years ago

=begin
樽家です。

2010年5月24日21:18 NARUSE, Yui naruse@airemix.jp:

成瀬です。

(2010/05/21 8:10), Masaya Tarui wrote:

Feature #2102 でString#inspectについては強制的にencodingを
揃えるようになりましたが、SymbolやRegexpについてはそうなっておらず、
同じような簡単にエラーになる状態になっています。ユーザー定義のinspectにも
同様です。またにinspectで文字コードの違いが区別できません。

Symbol と Regexp は忘れていました。
確かに対処が必要だと思います。

そこで、Kernel#pで表示する前やArrayやHashで各inspect結果をマージする前に、
String#inspectと同様な処理を行うのはどうでしょうか?具体的にはinspectで
想定するEncodingと異なる場合に、非ASCII文字をエスケープ表示にする
String#inspectencodeを追加し、それをrbinspectから呼ぶ事を提案したいと
思います。ASCII文字については手を加えないため、不可逆ですが実用上は問題
ないと思います。 ご検討をお願いします。

同様な処理といいながらなぜ新しい API を追加するんですか。

NARUSE, Yui naruse@airemix.jp

同様な処理といいながらなぜ新しい API を追加するんですか。

Featureなので、私的に思い切ってどう処理したら理想的だろうと考えた結果です。
同様な処理=inspect_encodeですが、結局Symbol型やRegexp型に限らず
必要になりそうなので分離したいと思いました。

これを導入した場合、元のString#Inspectを String#oldInspectとした場合、
String型aに対して、a.inspect と a.old
inspect.inspect_encode が同じになります。
なので、導入後にString#inspectを元に戻したとしてpの結果は変わりません。
ユーザー定義型の場合、inspectはしばしばユーザーが定義しますが、その時もケアして
やりたかったので、こういう形の提案になりました。

その前段階でユーザー定義のinspectはほっておいて、Symbol,Regexpの後処理と、Array,
Hashなど再帰的にItemのinspectを呼ぶものについて、String#inspect_encodeを被せても
いいかなとも思っています。
その場合、APIとして公開する必要はありませんし、pの定義も変わりませんので、穏当ではあります。

--
樽家昌也(Masaya TARUI)
No Tool,No Life.

=end

#3 Updated by Yukihiro Matsumoto almost 4 years ago

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

In message "Re: Re: [Feature #3328] Kernel#p outputs as default_internal encoding, and so on"
on Mon, 31 May 2010 19:16:38 +0900, Masaya TARUI tarui@prx.jp writes:

|樽家です。

|> 同様な処理といいながらなぜ新しい API を追加するんですか。
|
|Featureなので、私的に思い切ってどう処理したら理想的だろうと考えた結果です。
|同様な処理=inspect_encodeですが、結局Symbol型やRegexp型に限らず
|必要になりそうなので分離したいと思いました。

結論がないので申し訳ないのですが、encoding処理の理想は空気の
ように見えないことで、いつかの将来Unicodeが世界制覇した時に実
現されるのだと思います(実現するのであれば)。で、仮にこのAPIが
その頃まで残ったとすると、盲腸のように不要なものになることが
予想されます。それはAPIデザインとして筋が悪いのではないでしょ
うか。

=end

#4 Updated by Masaya Tarui almost 4 years ago

=begin
樽家です。

|> 同様な処理といいながらなぜ新しい API を追加するんですか。
|
|Featureなので、私的に思い切ってどう処理したら理想的だろうと考えた結果です。
|同様な処理=inspect_encodeですが、結局Symbol型やRegexp型に限らず
|必要になりそうなので分離したいと思いました。

結論がないので申し訳ないのですが、encoding処理の理想は空気の
ように見えないことで、いつかの将来Unicodeが世界制覇した時に実
現されるのだと思います(実現するのであれば)。で、仮にこのAPIが
その頃まで残ったとすると、盲腸のように不要なものになることが
予想されます。それはAPIデザインとして筋が悪いのではないでしょ
うか。

encoding処理の理想は空気のように見えないというのは確かに素晴らしいです。
私自身Encodingがうまく理解出来なくて、1.9に以降するのを本当に大分遅らせましたし、仕事で使っているのはいまだに1.8系という体たらくです。
ただ少なくとも、今すぐ実現するものではないでしょうし、そのころまでそのAPIが残ったとするのには無理が無いでしょうか?
少なくともString#encodeが消えるときには一緒に消えたら良いと思います。
当面はencodingに煩わされると仮定した現状での理想です。

# それとは別にまつもとさんも結論がないと言われている「空気のように見えない」は確かに欲しいですが、残念ながらこれといった提案が思い浮かばず今のところ出来ていません。

現在のString#inspectは
1)不可視文字(制御文字)の可視化である所のエスケープと、
2)元のエンコードが、表示エンコードと違う場合に強引に表示エンコードに合わせる処理(\x{xxxx}や\uxxxxへの置き換え)
を行っていますが、2)の元のエンコードが表示エンコードと違う場合に強引に表示エンコードに合わせる処理はSymbolやRegexp,Array,Hashで必要なように割と汎用的に欲しい機能です。
またpがユーザー定義のinspectを呼ぶ場合にも処理させたい機能だと思います。

おそらくEncoding::Converter#primitive_convertを使えば何とか同じ機能を実現できるんでしょうし、
これらの内部で使うだけにして非公開する という判断は先のメールに書いたように、それはそれでありです。

ただし、ユーザーがArrayの様な、内部でinspectを呼ぶクラスのinspcetを書くときにはEncodingに互換性が無いと起こられる
可能性がある限りは必要な変換ですし、公開した方がうれしい人が多いのではないと思います。

失敗せずになんらかしらの形で対象encodingに変換してくれる簡便なAPIが無いという現状のencoding環境はstrictですが、
プログラムしていて主にデバックで辛いです。

--
樽家昌也(Masaya TARUI)
No Tool,No Life.

=end

#5 Updated by Hiroshi Nakamura about 2 years ago

  • Description updated (diff)
  • Assignee set to Masaya Tarui

#6 Updated by Shyouhei Urabe about 2 years ago

  • Status changed from Open to Assigned

#7 Updated by Yutaka HARA over 1 year ago

  • Target version changed from 2.0.0 to next minor

Also available in: Atom PDF