Feature #3946
Array#packのqQ指定子に機種依存サイズフラグ!を追加
| Status: | Assigned | Start date: | 10/14/2010 | |
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | % Done: | 100% |
||
| Category: | - | |||
| Target version: | 2.0.0 |
Description
Ruby の伏魔殿 Array#pack ですが、機種依存な部分をいじる際にはしばしば強力かつ唯一の手段になる事があります。 具体的には RubySpec 書く時とか。 さて、q/Q は 64bit signed/unsigned int なのですが、機種依存の long long (厳密には LONG_LONG) のサイズが必要な場合、 現状 Ruby レベルから取る手段が一切ありません。 すでに s/S/i/I/l/L (16bit/32bit/32bit) は、! をつけることでその機種の short/int/long のサイズになるため、 これを q/Q に拡張すると唯一の手段が提供される事になります。 というわけで、Array#packのqQ指定子に機種依存サイズフラグ!を追加したいです。
Associated revisions
* pack.c (pack_pack): Add native size option ! to q and Q.
[ruby-dev:42375]
* pack.c (pack_unpack): ditto.
History
Updated by akr (Akira Tanaka) over 1 year ago
2010年10月14日15:36 Yui NARUSE <redmine@ruby-lang.org>: > Feature #3946: Array#packのqQ指定子に機種依存サイズフラグ!を追加 > http://redmine.ruby-lang.org/issues/show/3946 > > 起票者: Yui NARUSE > ステータス: Open, 優先度: Normal > Target version: 1.9.3 > > Ruby の伏魔殿 Array#pack ですが、機種依存な部分をいじる際にはしばしば強力かつ唯一の手段になる事があります。 > 具体的には RubySpec 書く時とか。 > > さて、q/Q は 64bit signed/unsigned int なのですが、機種依存の long long (厳密には LONG_LONG) のサイズが必要な場合、 > 現状 Ruby レベルから取る手段が一切ありません。 > すでに s/S/i/I/l/L (16bit/32bit/32bit) は、! をつけることでその機種の short/int/long のサイズになるため、 > これを q/Q に拡張すると唯一の手段が提供される事になります。 おそらく long long がない場合にはエラーになるべきだと思うんですが、 その場合のエラーを決めないといけないんじゃないでしょうか。 -- [田中 哲][たなか あきら][Tanaka Akira]
Updated by naruse (Yui NARUSE) over 1 year ago
(2010/10/14 21:07), Tanaka Akira wrote: >> さて、q/Q は 64bit signed/unsigned int なのですが、機種依存の long long (厳密には LONG_LONG) の >> サイズが必要な場合、現状 Ruby レベルから取る手段が一切ありません。 >> すでに s/S/i/I/l/L (16bit/32bit/32bit) は、! をつけることでその機種の short/int/long の >> サイズになるため、これを q/Q に拡張すると唯一の手段が提供される事になります。 > > おそらく long long がない場合にはエラーになるべきだと思うんですが、 > その場合のエラーを決めないといけないんじゃないでしょうか。 ふむ。 現実的には 64bit 以上の整数型がない環境ですよね。 rb_raise(rb_eArgError, "this machine doesn't have long long int"); あたりになりますかねぇ。 -- NARUSE, Yui <naruse@airemix.jp>
Updated by naruse (Yui NARUSE) over 1 year ago
2010年10月15日9:28 KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>:
>> (2010/10/14 21:07), Tanaka Akira wrote:
>> >> さて、q/Q は 64bit signed/unsigned int なのですが、機種依存の long long (厳密には LONG_LONG) の
>> >> サイズが必要な場合、現状 Ruby レベルから取る手段が一切ありません。
>> >> すでに s/S/i/I/l/L (16bit/32bit/32bit) は、! をつけることでその機種の short/int/long の
>> >> サイズになるため、これを q/Q に拡張すると唯一の手段が提供される事になります。
>> >
>> > おそらく long long がない場合にはエラーになるべきだと思うんですが、
>> > その場合のエラーを決めないといけないんじゃないでしょうか。
>>
>> ふむ。
>> 現実的には 64bit 以上の整数型がない環境ですよね。
>> rb_raise(rb_eArgError, "this machine doesn't have long long int");
>> あたりになりますかねぇ。
>
> あんまりRubyのexceptionのルールを知らないんですが、
>
> ・引数が間違っている
>
> だと、暗黙にプログラムがバグっているというニュアンスを持つので
>
> ・そのプラットフォームは未対応
>
> ってのは、違うエラーが一般的な気がします。Unix errnoルールでいうと
>
> EINVAL: 引数が待ちガットル
> ENOSYS: 未実装システムコール
>
> みたいな。
>
> 余談に走りますがglibc関係者がkernel開発者に以前この件で苦情を言ってきた
> 事があって、それは
>
> ・ユーザが引数を間違えて渡してきた時はエラーを返したい
> ・カーネルが古くて、新しめのシステムコールが未実装の時は
> 代替処理にfallbackしたい
>
> という事はわりとありがちなので混同しないで、とかいう話でした。
> 今回の件に当てはまるかどうかは分かりませんが。
一理あるとは思うのですが、
* packは後述の通り間違った指定子は無視する
* NotImplementedError が一見それに見えて確か違う……と見せかけてrdocみるとこれっぽいな
というわけで、rb_eNotImpError かも。
> ああ、でもこのへんもperlにあわせたほうがいいのかな?
Perl を見ると、
> (Quads are available only if your system supports 64-bit
> integer values _and_ if Perl has been compiled to support those.
> Raises an exception otherwise.)
> http://perldoc.perl.org/functions/pack.html
などとあり、実際試しても以下の通りエラーですね。
% perl -e'print pack("q",1)'
Invalid type 'q' in pack at -e line 1.
ちなみに、全く非対応な文字を食わせた場合、
% perl -e'print pack("o",1)'
Invalid type 'o' in pack at -e line 1.
% ruby -e'p [1].pack("O")'
""
すごく……仕様変更したいです……
--
NARUSE, Yui
naruse@airemix.jp
Updated by naruse (Yui NARUSE) over 1 year ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
This issue was solved with changeset r29527. Yui, thank you for reporting this issue. Your contribution to Ruby is greatly appreciated. May Ruby be with you.
Updated by akr (Akira Tanaka) over 1 year ago
2010年10月14日21:29 NARUSE, Yui <naruse@airemix.jp>: >> おそらく long long がない場合にはエラーになるべきだと思うんですが、 >> その場合のエラーを決めないといけないんじゃないでしょうか。 > > ふむ。 > 現実的には 64bit 以上の整数型がない環境ですよね。 64bit 以上の整数型なら何でもいいんですか? それなら、なんで現状の q, Q ではいけないんですか? -- [田中 哲][たなか あきら][Tanaka Akira]
Updated by naruse (Yui NARUSE) over 1 year ago
2010年10月18日13:26 Tanaka Akira <akr@fsij.org>: > 2010年10月14日21:29 NARUSE, Yui <naruse@airemix.jp>: > >>> おそらく long long がない場合にはエラーになるべきだと思うんですが、 >>> その場合のエラーを決めないといけないんじゃないでしょうか。 >> >> ふむ。 >> 現実的には 64bit 以上の整数型がない環境ですよね。 > > 64bit 以上の整数型なら何でもいいんですか? > > それなら、なんで現状の q, Q ではいけないんですか? 以下の通り、64bit 整数型が無い場合と、long long が 64bit 超な場合に差が出ますね。 MSVC の場合に __int64 を使わず例外にするというパターンもありますが、 現実的には CRuby は常に LONG_LONG でラップしている訳で、 ラップ後を用いた方が現実に即していると考えています。 = long long がある == long long が 64bit q: 64bit q!: 64bit == long long が 64bit 超 q: 64bit q!: 64bit超 128bitとか = long long がない == 64bit 整数型がある → LONG_LONG はたぶん 64bit (eg. MSVC++) q: 64bit q!: どうあるべきか (現状: LONG_LONGに追従) == 64bit 整数型はないが64bit 超はある q: 64bit (自力で頑張る) q!: どうあるべきか (LONG_LONGに追従、無ければ例外) == 64bit 以上の型が無い q: 64bit (自力で頑張る) q!: 例外 (LONG_LONGもないはずである) -- NARUSE, Yui naruse@airemix.jp
Updated by akr (Akira Tanaka) over 1 year ago
2010年10月18日14:04 NARUSE, Yui <naruse@airemix.jp>: >> >> 64bit 以上の整数型なら何でもいいんですか? >> >> それなら、なんで現状の q, Q ではいけないんですか? > > 以下の通り、64bit 整数型が無い場合と、long long が 64bit 超な場合に差が出ますね。 > MSVC の場合に __int64 を使わず例外にするというパターンもありますが、 > 現実的には CRuby は常に LONG_LONG でラップしている訳で、 > ラップ後を用いた方が現実に即していると考えています。 違うときに、q でなく q! が (あるいは Q でなく Q! が) 役に立つということを、 具体的な例を使って説明してほしいんですが、そういう説明はないんでしょうか。 私は、LONG_LONG というのは CRuby 固有なものなので、 一般のアプリケーションには役に立たないのではないか、という点を疑っています。 -- [田中 哲][たなか あきら][Tanaka Akira]
Updated by naruse (Yui NARUSE) over 1 year ago
衝突してるのはよくないのでとりあえず revert します。 -- NARUSE, Yui naruse@airemix.jp
Updated by naruse (Yui NARUSE) over 1 year ago
2010年10月18日15:26 NARUSE, Yui <naruse@airemix.jp>: > 衝突してるのはよくないのでとりあえず revert します。 あれ、本文が消えてる……。 Bignum 絡みで使おうと思っていたが、一方でFFI などは素の long long が欲しい気もする。 つまり、矛盾するユースケースが予想されるので却下とする、という趣旨の事を書いていました。 -- NARUSE, Yui naruse@airemix.jp
Updated by usa (Usaku NAKAMURA) over 1 year ago
- Status changed from Closed to Open
ユースケース1件発生しました。r29925を参照。 というわけで、q!(Q!)をLONG_LONGとして扱うという仕様を希望します。 LONG_LONGがないプラットフォームは現状サポート外だと思いますが、 その場合はArgumentErrorあたりでしょうか。
Updated by akr (Akira Tanaka) over 1 year ago
2010年11月25日10:57 Usaku NAKAMURA <redmine@ruby-lang.org>: > チケット #3946 が更新されました。 (by Usaku NAKAMURA) > ユースケース1件発生しました。r29925を参照。 > > というわけで、q!(Q!)をLONG_LONGとして扱うという仕様を希望します。 > LONG_LONGがないプラットフォームは現状サポート外だと思いますが、 > その場合はArgumentErrorあたりでしょうか。 あまりよくわかっていないんですが、これって Q! で生成したデータを 受けとるのは Ruby 内部なんじゃないでしょうか。 もしそうなら、CRuby 固有のものだから一般のアプリケーションには 役に立たない、という私の懸念は晴れないのですが、実際はどうなんでしょう? CRuby 固有のものを扱うのは pack にはいままでない (と思う) ので 気に入らないのですが、CRuby 固有のものが役に立たないというわけではありません。 実際、CRuby を相手にする時には役に立つでしょう。 なんとなく rbconfig あたりに LONG_LONG の有無やサイズ (やアラインメント) を 記録しておくあたりで済ますのがいい気がするんですが、どうですかね。 (他の型についても記録しておくことも考えられるでしょう。) 記録してある情報から pack に使える形式に変換するのが面倒かもしれませんが。 -- [田中 哲][たなか あきら][Tanaka Akira]
Updated by naruse (Yui NARUSE) 11 months ago
- Target version changed from 1.9.3 to 2.0.0
Updated by akr (Akira Tanaka) 3 months ago
2012年2月9日16:47 U.Nakamura <usa@garbagecollect.jp>:
>
> 古いチケットですが、r34507でまた踏んだので蒸し返します。
>
> In message "[ruby-dev:42671] Re: [Ruby 1.9-Feature#3946][Open] Array#packのqQ指定子に機種依存サイズフラグ!を追加"
> on Dec.02,2010 21:30:53, <akr@fsij.org> wrote:
>> あまりよくわかっていないんですが、これって Q! で生成したデータを
>> 受けとるのは Ruby 内部なんじゃないでしょうか。
>
> 質問に質問で返すのはよくないですが、「Ruby内部」ってどこまで
> を想定しておられますか。
> 前回も今回も踏んでるのはDLですが、DLはつまりRubyの外のコード
> を呼ぶためにこの辺のデータをごにょごにょしているので、外部の
> ような気がします。
前回の r29925 を見直してみたのですが、
* ext/dl/callback/mkcallback.rb (gencallback): shouldn't assume that
VALUE is the same size with long.
と書いてあって、VALUE のサイズが問題だったのではないでしょうか。
VALUE っていうのは Ruby 内部だと思います。
今回の r34507 は、みたところあまり内部っぽい感じはしませんね。
> LONG_LONGという言葉を使うとCRuby固有に聞こえますけど、要する
> にlong longのデータをどう扱いますか、ということなので、あまり
> LONG_LONGという字面にとらわれて考える必要はないと思います。
純粋に C の long long を実現するもので、
long long が存在しないときの挙動に合意が取れるなら
それはとくに問題ないんじゃないでしょうか。
--
[田中 哲][たなか あきら][Tanaka Akira]
Updated by usa (Usaku NAKAMURA) 3 months ago
こんにちは、なかむら(う)です。
In message "[ruby-dev:45216] Re: [Ruby 1.9-Feature#3946][Open] Array#packのqQ指定子に機種依存サイズフラグ!を追加"
on Feb.09,2012 17:03:19, <akr@fsij.org> wrote:
> > 質問に質問で返すのはよくないですが、「Ruby内部」ってどこまで
> > を想定しておられますか。
> > 前回も今回も踏んでるのはDLですが、DLはつまりRubyの外のコード
> > を呼ぶためにこの辺のデータをごにょごにょしているので、外部の
> > ような気がします。
>
> 前回の r29925 を見直してみたのですが、
>
> * ext/dl/callback/mkcallback.rb (gencallback): shouldn't assume that
> VALUE is the same size with long.
>
> と書いてあって、VALUE のサイズが問題だったのではないでしょうか。
> VALUE っていうのは Ruby 内部だと思います。
>
> 今回の r34507 は、みたところあまり内部っぽい感じはしませんね。
あー、確かに、前回はそんな感じだったかもしれません。
> > LONG_LONGという言葉を使うとCRuby固有に聞こえますけど、要する
> > にlong longのデータをどう扱いますか、ということなので、あまり
> > LONG_LONGという字面にとらわれて考える必要はないと思います。
>
> 純粋に C の long long を実現するもので、
> long long が存在しないときの挙動に合意が取れるなら
> それはとくに問題ないんじゃないでしょうか。
ふむ。
では、以前も述べたように存在しないときの挙動はArgumentErrorで
よいと思いますが、誰か異論がある人はいますでしょうか?
それでは。
--
U.Nakamura <usa@garbagecollect.jp>
Updated by kosaki (Motohiro KOSAKI) 3 months ago
>> > LONG_LONGという言葉を使うとCRuby固有に聞こえますけど、要する
>> > にlong longのデータをどう扱いますか、ということなので、あまり
>> > LONG_LONGという字面にとらわれて考える必要はないと思います。
>>
>> 純粋に C の long long を実現するもので、
>> long long が存在しないときの挙動に合意が取れるなら
>> それはとくに問題ないんじゃないでしょうか。
>
> ふむ。
>
> では、以前も述べたように存在しないときの挙動はArgumentErrorで
> よいと思いますが、誰か異論がある人はいますでしょうか?
現実的な範囲ではどのコンパイラもソフトウェアエミュレーションでint64_t を
サポートできているようなので細かい話ですがプラットフォームの都合で
失敗するときに ArgumentError にするのはあまり好きではありません。
この状況で失敗したときってアプリ側でfallbackが書けるケースはまれで
そのまま終了するのですが、ArgumentError だとアプリケーションにバグが
あることを暗に言っているのでミスリーディングだと思うのです。
また、逆にfallbackが書けるケースでいうとプラットフォームが非対応のときは
fallbackしたいけど、それ以外のときはfallback したくないはずなのです。
それ以外というのは、よばだし側がライブラリでさらに上位のアプリケーションが
間違った引数をわたしてきた場合、ということですが。
# だけど NotImpErrorは %s() funcsion is unimplemented だから関数にしか使えないんだよねえ。使えない奴・・
Updated by usa (Usaku NAKAMURA) 3 months ago
こんにちは、なかむら(う)です。
In message "[ruby-dev:45219] Re: [Ruby 1.9-Feature#3946][Open] Array#packのqQ指定子に機種依存サイズフラグ!を追加"
on Feb.10,2012 02:45:01, <kosaki.motohiro@gmail.com> wrote:
> > では、以前も述べたように存在しないときの挙動はArgumentErrorで
> > よいと思いますが、誰か異論がある人はいますでしょうか?
>
> 現実的な範囲ではどのコンパイラもソフトウェアエミュレーションでint64_t を
> サポートできているようなので細かい話ですがプラットフォームの都合で
> 失敗するときに ArgumentError にするのはあまり好きではありません。
64bit整数のpack/unpackを意味するフォーマット指定子 "q" "Q" は
既にあって、int64_tがあろうがなかろうが動作するようになってい
ます。
今している話はこれをArgumentErrorにする、という話ではありませ
ん。
このticketはlong long(Rubyソースコード上ではLONG_LONG)を意味
するフォーマット指定子 "q!" "Q!" を追加しましょう、という提案
であり、「存在しないとき」云々はlong longがない場合はどーしま
しょーか、という話なので、int64_tがあるかどうかとは理論上は関
係がございません。
# 現実問題として今はどこでも両者は同じなんでしょうけど。
> この状況で失敗したときってアプリ側でfallbackが書けるケースはまれで
> そのまま終了するのですが、ArgumentError だとアプリケーションにバグが
> あることを暗に言っているのでミスリーディングだと思うのです。
なお、long longがないプラットフォームで "q!" "Q!" を使おうと
するのはどう考えてもバグなので、お前のバグだろゴルァと例外を
投げるのは完全に真っ当なエラー指摘だと思います。
それでは。
--
U.Nakamura <usa@garbagecollect.jp>
Updated by kosaki (Motohiro KOSAKI) 3 months ago
(2/9/12 2:19 PM), U.Nakamura wrote:
> こんにちは、なかむら(う)です。
>
> In message "[ruby-dev:45219] Re: [Ruby 1.9-Feature#3946][Open] Array#packのqQ指定子に機種依存サイズフラグ!を追加"
> on Feb.10,2012 02:45:01,<kosaki.motohiro@gmail.com> wrote:
>>> では、以前も述べたように存在しないときの挙動はArgumentErrorで
>>> よいと思いますが、誰か異論がある人はいますでしょうか?
>>
>> 現実的な範囲ではどのコンパイラもソフトウェアエミュレーションでint64_t を
>> サポートできているようなので細かい話ですがプラットフォームの都合で
>> 失敗するときに ArgumentError にするのはあまり好きではありません。
>
> 64bit整数のpack/unpackを意味するフォーマット指定子 "q" "Q" は
> 既にあって、int64_tがあろうがなかろうが動作するようになってい
> ます。
> 今している話はこれをArgumentErrorにする、という話ではありませ
> ん。
>
> このticketはlong long(Rubyソースコード上ではLONG_LONG)を意味
> するフォーマット指定子 "q!" "Q!" を追加しましょう、という提案
> であり、「存在しないとき」云々はlong longがない場合はどーしま
> しょーか、という話なので、int64_tがあるかどうかとは理論上は関
> 係がございません。
> # 現実問題として今はどこでも両者は同じなんでしょうけど。
うーん、int64と書いたのがよくなかったのかな。意図は LONG_LONGであって
「long longっぽい何か」のつもりで使っていました。
>> この状況で失敗したときってアプリ側でfallbackが書けるケースはまれで
>> そのまま終了するのですが、ArgumentError だとアプリケーションにバグが
>> あることを暗に言っているのでミスリーディングだと思うのです。
>
> なお、long longがないプラットフォームで "q!" "Q!" を使おうと
> するのはどう考えてもバグなので、お前のバグだろゴルァと例外を
> 投げるのは完全に真っ当なエラー指摘だと思います。
いや、それは違います。やってみるまでそういう環境かどうかは分からないので。
Updated by usa (Usaku NAKAMURA) 3 months ago
こんにちは、なかむら(う)です。
古いチケットですが、r34507でまた踏んだので蒸し返します。
In message "[ruby-dev:42671] Re: [Ruby 1.9-Feature#3946][Open] Array#packのqQ指定子に機種依存サイズフラグ!を追加"
on Dec.02,2010 21:30:53, <akr@fsij.org> wrote:
> あまりよくわかっていないんですが、これって Q! で生成したデータを
> 受けとるのは Ruby 内部なんじゃないでしょうか。
質問に質問で返すのはよくないですが、「Ruby内部」ってどこまで
を想定しておられますか。
前回も今回も踏んでるのはDLですが、DLはつまりRubyの外のコード
を呼ぶためにこの辺のデータをごにょごにょしているので、外部の
ような気がします。
> もしそうなら、CRuby 固有のものだから一般のアプリケーションには
> 役に立たない、という私の懸念は晴れないのですが、実際はどうなんでしょう?
LONG_LONGという言葉を使うとCRuby固有に聞こえますけど、要する
にlong longのデータをどう扱いますか、ということなので、あまり
LONG_LONGという字面にとらわれて考える必要はないと思います。
それでは。
--
U.Nakamura <usa@garbagecollect.jp>
Updated by shyouhei (Shyouhei Urabe) 2 months ago
- Status changed from Open to Assigned