-
Notifications
You must be signed in to change notification settings - Fork 315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
String#to_json の説明 #1651
Comments
もう一つの問題点を書き忘れました。 #1646 のほうに書いたのですが,RFC 8259 によれば, 参考:RFC 8259 — The JavaScript Object Notation (JSON) Data Interchange Format の「7. Strings」 しかるに, なぜ RFC 8259 に従っていないのかは分からないですが,従わない理由を書くか,それが無理でも,注意を喚起する必要があると思います。 |
とりあえずここをもう少し詳しく書いていただけるとありがたいです。本体に含まれてないですが、以下のあたりの話かもしれませんね。とだけ思いました。 |
まず,「RFC 8259 に従っていない」は事実無根でした。すみません。BMP 外の文字の さて
につきまして。 一方, ただ なお,当該の コメント
は,直後の どんな場合に
ということであるようです。 |
詳しく調べていませんが, |
ありがとうございます。
\u 自体の表現の仕方の範囲ではエンディアンとは無関係というところまではわかったような気がします。 一方で、RFC 8259 のサロゲートペアのサンプルに言及いただいてますが、以下を試す範囲では Encoding::UTF_16BE な文字を返してるのではないのか?とも思います。
ところで、\u 表記を使った時の文字エンコードをどう識別するのかわかってないのですが、\u 表記で UTF-8 も UTF-16 BE も表す事ができるとすれば\u 表記を行ってエスケープした文字列を使ったJSONは UTF-8 で記述する仕様から外れていないのではないか?とも思ったりします。ただ、これが的を得ているのかがよくわかりませんでした。 参照いただいてるのだと思いますが、 RFC 8259 の 7. Strings を見ますと以下の辺りで件の文字も出てきます。
これを読む分には、
のではないかと思いました。 ただし、「"\u????" のように」と説明を始めてしまうと \u 表記全般が「UTF-16 BEな文字列である」と読めてしまうかもしれないとは思いましたので、説明をもう少し考えてもいいのではないかと思いました。 |
の意味がちょっとよく分かりませんでした。 RFC 8259 が求めているのは,文字を
ということだと思います(実際 Ruby の json はそのように動作しています)。
と。 サロゲートペアは UTF-16 のために考案されたもので,それを用いて RFC 8259 に「UTF-16」は 3 箇所に出てきます。
のところ。(この「encoding」はサロゲートペア化のことと思われます) |
すみません、ここがよくわかりませんでした。「内部で使っていますが」とありますが、今のところその結果をそのまま返してると思っています。上で挙げた以下のコードの部分です。
ちなみにですが、どう修正して欲しいのでしょうか? @scivola さんの主張が正しい場合、最も詳しいと思いますので、修正内容もわかるのではないかと思います。以下の2点を整理していただけるとありがたいですね。
|
(細かい仕組みよりも「戻り値がどういう値」だからエンディアンが関係ないという話をしていただく方が個人的にうれしいですね。 |
すれ違いの原因が判ったような気がします。 掲げていただいた puts "\u{1D11E}".to_json(ascii_only: true)
# => "\ud834\udd1e" ですが, ↓こちらのほうが分かりやすいかもしれません。 p "\u{1D11E}".to_json(ascii_only: true).chars
# => ["\"", "\\", "u", "d", "8", "3", "4", "\\", "u", "d", "d", "1", "e", "\""] この と,こういう話で納得していただけそうでしょうか。
修正提案が書けなかったのは,私自身,よく分かってなかったからなのですが,だんだん分かってきました。 |
うーん、残念ながらわかってないです。
はい。(前コメントのお話とは関係なく)その通りだと思っています。
"\ud834\udd1e" が表す文字のエンコーディングがUTF-16BEなのだという主張をコード例で示していたつもりでした。素性がよくわかってないサイト(僕が知らないだけですけども)ですが、以下などでもそう見えます。
と書かれていますけども、別の例ではUTF-16LE、UTF-16でencodeして異なる値が出てますので、やはりUTF-16 BEなのではないかという認識ですね。サロゲートペアのお話よりも、まずこの辺りを否定してもらえるのが一番ありがたいというところですね。 |
すると, そして,問題の焦点はサロゲートペアにはなさそうですので,三日前のコメント に戻っちゃいますが,「あ」で考えたいと思います。 「あ」を UTF-16 BE で表すと,第 1 バイトが 0x30,第 2 バイトが 0x42 になります。 それで, "あ".to_json(ascii_only: true) が返す UTF-16 BE は,コードポイントの数値を上位 8 bit →下位 8 bit の順に並べた物なので,そのバイト列を 16 進表記すれば,当然,コードポイントの数値を 4 桁の 16 進数で表したものと一致します。 しかし,そのことをもって |
いえ、そうとは一度も言ってないです。再掲しますが僕の見解は引き続き以下ですね。
改めてですが、問題にされている文言は以下ですよね。
「ことがある」という文言に「UTF-16BEの文字を表す\u表記が登場し得る」という解釈をしています。この時に以下のようにコメントしています。
「\u 表記とUTF-16BEを切り離す」という修正は最低限必要だとは思っていますという事ですね。 ただ、たとえば「ascii_onlyオプションを指定した場合に、UTF-16ビッグエンディアンでエンコードされた文字列を表す \u???? 形式の文字列を返します」と修正すればOKなのか、それでは足りないのかはわかっていません。(...切り離せていない気がしますけど、それは一旦おいておきます)
たまたま別の文字エンコーディングでも同じ値を示す文字の事を話しているのでは?という事であればその通りだと思います。 ただ、(解釈があっていれば)それは流石に具体的に反証をコードで例示していただくとありがたいです。テストコードとか見ていただくといいかもしれませんね。 |
ところでjsonライブラリとしての\u表記の定義というものがあるかないかが気になっていたのですが、少し探しましたけどなさそうですね。 それが存在しないようなら一般的なものを見たらいいかとおもうのですが、そこに「U+3042を\u3042と表記します」のような記載があるなら、「それでは足りないのかはわかっていません」の部分は明らかに足りませんと考えると思います。 もしそうなら、修正内容は割と単純だったりするのだろうか?とも思ったりするのですが... |
用語の意味についての認識が一部食い違っているのかも,という気がしています。
における「UTF-16 BE な文字列」「UTF-16 BE の文字」が何を意味するのか私にはよく分からないです。 UTF-16 BE は符号化方式(バイト列を構成する方式)の名前なので,「UTF-16 BE な文字列」という表現を見たら,私は「UTF-16 BE にしたがって作られたバイト列なんだな」と考えます。 それから
ですが,「ライブラリーとしての定義」というのがよく分かりませんでした。
(英語苦手なので 100% の自信は無いのですが) json ライブラリーではこれをそのまま実装しているように思われます。 |
やっとわかって来た気がします。あとでもう一度読もうと思いますが、やはりどう直せばいいのか、 @scivola さんご存知なのでは? |
はい,修正の下案を作ってみようと思っているのですが,その前に |
JSON::Generator::GeneratorMethods::String#to_json の説明に
とありますが,
\uXXXX
の表記はエンディアンに関係がないので「UTF-16 ビッグエンディアンで」は何かの間違いだと思います。関連 #1646
The text was updated successfully, but these errors were encountered: