Feature #3947

Array#packのにエンディアン指定修飾子</>を追加

Added by Yui NARUSE over 3 years ago. Updated almost 3 years ago.

[ruby-dev:42376]
Status:Closed
Priority:Normal
Assignee:-
Category:-
Target version:1.9.3

Description

=begin
Ruby の伏魔殿 Array#pack ですが、機種依存な部分をいじる際にはしばしば強力かつ唯一の手段になる事があります。
具体的には RubySpec 書く時とか。

さて、pack のようにバイト列を扱う場合、しばしば問題になるのがエンディアンです。
ここで、Ruby の Array#pack は 16bit/32bit 固定の整数に対してはエンディアン固定の
n/N/v/V 指定子を用意していますが、short/int/long/long long のように、
マシン依存の型をエンディアン固定で pack する手段を提供していません。
というわけで、これが欲しいです。

ここで問題になるのがどのように指定するかなのですが、pack のネタ元である Perl さんでは既に </> 修飾子を
この目的のために提供しています。
http://perldoc.perl.org/functions/pack.html
というわけで、これに追従するのがよろしいと思います。

 >   sSiIlLqQ   Force big-endian byte-order on the type.
     jJfFdDpP   (The "big end" touches the construct.)
 <   sSiIlLqQ   Force little-endian byte-order on the type.
     jJfFdDpP   (The "little end" touches the construct.)

なお、「</> とかきもい」という意見もあるかとは思いますが、pack は機種依存とかに触るきもいメソッドなので、
そこを気にするよりは長い物に巻かれておいた方が無難ではないかなと思うため、</> 修飾子がベストかと思います。
=end


Related issues

Related to ruby-trunk - Feature #4084: pack should support 64bit network byte order longs Closed 11/24/2010
Duplicates ruby-trunk - Feature #3491: Pack missing directives for signed types with specified b... Closed 06/28/2010

History

#1 Updated by Yukihiro Matsumoto over 3 years ago

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

In message "Re: [Ruby 1.9-Feature#3947][Open] Array#packのにエンディアン指定修飾子</>を追加"
on Thu, 14 Oct 2010 15:46:44 +0900, Yui NARUSE redmine@ruby-lang.org writes:

|さて、pack のようにバイト列を扱う場合、しばしば問題になるのがエンディアンです。
|ここで、Ruby の Array#pack は 16bit/32bit 固定の整数に対してはエンディアン固定の
|n/N/v/V 指定子を用意していますが、short/int/long/long long のように、
|マシン依存の型をエンディアン固定で pack する手段を提供していません。
|というわけで、これが欲しいです。
|
|ここで問題になるのがどのように指定するかなのですが、pack のネタ元である Perl さんでは既に </> 修飾子を
|この目的のために提供しています。
|http://perldoc.perl.org/functions/pack.html
|というわけで、これに追従するのがよろしいと思います。
|
| > sSiIlLqQ Force big-endian byte-order on the type.
| jJfFdDpP (The "big end" touches the construct.)
| < sSiIlLqQ Force little-endian byte-order on the type.
| jJfFdDpP (The "little end" touches the construct.)

賛成します。

=end

#2 Updated by Akira Tanaka over 3 years ago

=begin
2010年10月14日15:46 Yui NARUSE redmine@ruby-lang.org:

Feature #3947: Array#packのにエンディアン指定修飾子</>を追加
http://redmine.ruby-lang.org/issues/show/3947

起票者: Yui NARUSE
ステータス: Open, 優先度: Normal
Target version: 1.9.3

Ruby の伏魔殿 Array#pack ですが、機種依存な部分をいじる際にはしばしば強力かつ唯一の手段になる事があります。
具体的には RubySpec 書く時とか。

さて、pack のようにバイト列を扱う場合、しばしば問題になるのがエンディアンです。
ここで、Ruby の Array#pack は 16bit/32bit 固定の整数に対してはエンディアン固定の
n/N/v/V 指定子を用意していますが、short/int/long/long long のように、
マシン依存の型をエンディアン固定で pack する手段を提供していません。
というわけで、これが欲しいです。

ここで問題になるのがどのように指定するかなのですが、pack のネタ元である Perl さんでは既に </> 修飾子を
この目的のために提供しています。
http://perldoc.perl.org/functions/pack.html
というわけで、これに追従するのがよろしいと思います。

http://redmine.ruby-lang.org/issues/show/3491 によく似ている?
--
[田中 哲][たなか あきら][Tanaka Akira]

=end

#3 Updated by Yui NARUSE over 3 years ago

=begin
たしかに #3491 と重複しているようなしていないような。
見落としていました、ありがとうございます。

なお、signed とか型の大きさ可搬性絡みは、1.9 になるときに Perl を参考にしつつ
もっぱら rdoc の整備という形で再定義されたと理解しています、
という話を後で英語でも書きます。
=end

#4 Updated by Yui NARUSE over 3 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

=begin
This issue was solved with changeset r29496.
Yui, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.

=end

#5 Updated by Akira Tanaka over 3 years ago

=begin
2010年10月14日21:36 Yui NARUSE redmine@ruby-lang.org:

なお、signed とか型の大きさ可搬性絡みは、1.9 になるときに Perl を参考にしつつ
もっぱら rdoc の整備という形で再定義されたと理解しています、
という話を後で英語でも書きます。

私が整理したのはもっと後だったと思いますが。

なお、私としては、l! などを個々に記述して、対応する C の型を
それぞれに書いたのは、そちらのほうがわかりやすいだろうという思いがありました。

あと、i, I の記述が消えていますね。
--
[田中 哲][たなか あきら][Tanaka Akira]

=end

#6 Updated by Yui NARUSE over 3 years ago

=begin
2010年10月15日8:01 Tanaka Akira akr@fsij.org:

2010年10月14日21:36 Yui NARUSE redmine@ruby-lang.org:

なお、signed とか型の大きさ可搬性絡みは、1.9 になるときに Perl を参考にしつつ
もっぱら rdoc の整備という形で再定義されたと理解しています、
という話を後で英語でも書きます。

私が整理したのはもっと後だったと思いますが。

そういえば去年か今年あたりでしたっけか。

なお、私としては、l! などを個々に記述して、対応する C の型を
それぞれに書いたのは、そちらのほうがわかりやすいだろうという思いがありました。

<, > を追加すると組み合わせが増えるので別に書いた方がわかりやすいと思ったので変えました。

あと、i, I の記述が消えていますね。

が、i, I を追加しようとすると別だといまいち綺麗にならない事を理解したので、
それぞれ書くように戻しました。

--
NARUSE, Yui
naruse@airemix.jp

=end

#7 Updated by Akira Tanaka over 3 years ago

=begin
2010年10月15日16:35 NARUSE, Yui naruse@airemix.jp:

なお、私としては、l! などを個々に記述して、対応する C の型を
それぞれに書いたのは、そちらのほうがわかりやすいだろうという思いがありました。

<, > を追加すると組み合わせが増えるので別に書いた方がわかりやすいと思ったので変えました。

あと、i, I の記述が消えていますね。

が、i, I を追加しようとすると別だといまいち綺麗にならない事を理解したので、
それぞれ書くように戻しました。

えぇ、組み合わせ的に増えていくのを全部書くのが良くないというのもわかるのです。

読むのも大変ですし、全体の機能を把握するのも困難です。
また、書き間違えることもあります。
(実際、s!>, l!>, q!> のところはおかしいですね。)

でも、具体的に指定する方法が書いてあると、
pack の玄人以外にとってわかりやすく便利なのだという確信もあります。
常に任意の組み合わせができるわけではありませんし。

というわけでこんなでどうですかね。

% svn diff --diff-cmd diff -x '-u -p' pack.c
Index: pack.c
===================================================================
--- pack.c (revision 29504)
+++ pack.c (working copy)
@@ -338,37 +338,19 @@ static unsigned long utf8touv(const ch
* i, i, i! | Integer | signed int, native endian
* l
, l! | Integer | signed long, native endian
* | |
- * S> | Integer | 16-bit unsigned, big endian
- * L> | Integer | 32-bit unsigned, big endian
- * Q> | Integer | 64-bit unsigned, big endian
- * s> | Integer | 16-bit signed, big endian
- * l> | Integer | 32-bit signed, big endian
- * q> | Integer | 64-bit signed, big endian
+ * S> L> Q> | Integer | same as the directives without ">" except
+ * s> l> q> | | big endian
+ * S!> I!> | |
+ * L!> Q!> | |
+ * s!> i!> | |
+ * l!> q!> | |
* | |
- * S< | Integer | 16-bit unsigned, little endian
- * L< | Integer | 32-bit unsigned, little endian
- * Q< | Integer | 64-bit unsigned, little endian
- * s< | Integer | 16-bit signed, little endian
- * l< | Integer | 32-bit signed, little endian
- * q< | Integer | 64-bit signed, little endian
- * | |
- * S!> | Integer | unsigned short, big endian
- * I!> | Integer | unsigned int, big endian
- * L!> | Integer | unsigned long, big endian
- * Q!> | Integer | unsigned long long, big endian
- * s!> | Integer | signed, big endian
- * i!> | Integer | signed int, big endian
- * l!> | Integer | signed, big endian
- * q!> | Integer | signed, big endian
- * | |
- * S!< | Integer | unsigned short, little endian
- * I!< | Integer | unsigned int, little endian
- * L!< | Integer | unsigned long, little endian
- * Q!< | Integer | unsigned long long, little endian
- * s!< | Integer | signed short, little endian
- * i!< | Integer | signed int, little endian
- * l!< | Integer | signed long, little endian
- * q!< | Integer | signed long long, little endian
+ * S< L< Q< | Integer | same as the directives without "<" except
+ * s< l< q< | | little endian
+ * S!< I!< | |
+ * L!< Q!< | |
+ * s!< i!< | |
+ * l!< q!< | |
* | |
* n | Integer | 16-bit unsigned, network (big-endian) byte order
* N | Integer | 32-bit unsigned, network (big-endian) byte order
--
[田中 哲][たなか あきら][Tanaka Akira]

=end

#8 Updated by Yui NARUSE over 3 years ago

=begin
2010年10月15日18:43 Tanaka Akira akr@fsij.org:

2010年10月15日16:35 NARUSE, Yui naruse@airemix.jp:

なお、私としては、l! などを個々に記述して、対応する C の型を
それぞれに書いたのは、そちらのほうがわかりやすいだろうという思いがありました。

<, > を追加すると組み合わせが増えるので別に書いた方がわかりやすいと思ったので変えました。

あと、i, I の記述が消えていますね。

が、i, I を追加しようとすると別だといまいち綺麗にならない事を理解したので、
それぞれ書くように戻しました。

えぇ、組み合わせ的に増えていくのを全部書くのが良くないというのもわかるのです。

読むのも大変ですし、全体の機能を把握するのも困難です。
また、書き間違えることもあります。
(実際、s!>, l!>, q!> のところはおかしいですね。)

おぉ、たしかに。

でも、具体的に指定する方法が書いてあると、
pack の玄人以外にとってわかりやすく便利なのだという確信もあります。
常に任意の組み合わせができるわけではありませんし。

というわけでこんなでどうですかね。

% svn diff --diff-cmd diff -x '-u -p' pack.c

なるほど、良いのではないかと思います。
コミットお願いします。

--
NARUSE, Yui
naruse@airemix.jp

=end

Also available in: Atom PDF