Misc #15615
Updated by nobu (Nobuyoshi Nakada) over 5 years ago
`File.birthtime`はファイルの作成時刻を返すメソッドです。 File.birthtimeはファイルの作成時刻を返すメソッドです。 これまでLinux環境ではこのメソッドは実装されておらず、呼び出すと`NotImplementedError`が発生していましたが、r67088から一部のLinux環境でも`File.birthtime`が動作するようになりました。 これまでLinux環境ではこのメソッドは実装されておらず、呼び出すとNotImplementedErrorが発生していましたが、r67088から一部のLinux環境でもFile.birthtimeが動作するようになりました。 Linux環境での`File.birthtime`は、`statx()`というLinux Linux環境でのFile.birthtimeは、statx()というLinux 4.11から導入されたシステムコールを使うことで実装されています。 `statx()`には以下の特徴があります。 statx()には以下の特徴があります。 1. `stat()`では取得できなかった情報が取れる stat()では取得できなかった情報が取れる * ファイル作成時刻 * 圧縮や暗号化の有無などの属性 2. どの情報に興味があるかをマスクで指定して使う * 指定した情報が返されるとは限らず、指定していない情報まで返される場合もある * 指定された情報の一部または全部を返せなかった場合でも戻り値は0であり、`errno`もセットされない 指定された情報の一部または全部を返せなかった場合でも戻り値は0であり、errnoもセットされない 3. `struct statx`という`struct stat`とは異なる構造体を返す struct statxというstruct statとは異なる構造体を返す 4. 返された`statx`構造体のうち、どの情報が有効であるかは`stx_mask`というメンバに格納される 返されたstatx構造体のうち、どの情報が有効であるかはstx_maskというメンバに格納される `statx()`でファイルの作成時刻が得られるかどうかはファイルシステム依存であり、有効な値が得られない場合があります。 statx()でファイルの作成時刻が得られるかどうかはファイルシステム依存であり、有効な値が得られない場合があります。 2.に挙げたように、`statx()`はこの場合でも0を返し`errno`もセットされません。 2.に挙げたように、statx()はこの場合でも0を返しerrnoもセットされません。 r67088では、`stx_mask`を参照して作成時刻が有効であるかどうかを確かめ、無効であった場合は`NotImplementedError`を`raise`します。 r67088では、stx_maskを参照して作成時刻が有効であるかどうかを確かめ、無効であった場合はNotImplementedErrorをraiseします。 `File.birthtime`は`Time`を返すことが期待されているので、値が無効だからといって`nil`を返す訳にもいかないと考えたからです。 File.birthtimeはTimeを返すことが期待されているので、値が無効だからといってnilを返す訳にもいかないと考えたからです。 しかし、`NotImplementedError`はプラットフォーム依存で機能の実装・未実装が異なる場合に用いられていることが多いようです。 しかし、NotImplementedErrorはプラットフォーム依存で機能の実装・未実装が異なる場合に用いられていることが多いようです。 少なくともfile.cの他の部分では`NotImplementedError`はそのように使われています。 少なくともfile.cの他の部分ではNotImplementedErrorはそのように使われています。 また、spec/ruby/core/file/birthtime_spec.rbには以下のような部分があります。 ```ruby platform_is :linux, :openbsd do it "raises an NotImplementedError" do lambda { File.birthtime(@file) }.should raise_error(NotImplementedError) end end ``` このテスト自体の是非はともかく、このように`NotImplementedError`がプラットフォーム依存で発生するものと期待されている面はあるのではないかと思います。 このテスト自体の是非はともかく、このようにNotImplementedErrorがプラットフォーム依存で発生するものと期待されている面はあるのではないかと思います。 そう考えると、ファイルシステム依存で`NotImplementedError`を発生させることは好ましくないかもしれません。 そう考えると、ファイルシステム依存でNotImplementedErrorを発生させることは好ましくないかもしれません。 ※ r67115では`Errno::ENOSYS`を発生させるよう変更されました。 r67115ではErrno::ENOSYSを発生させるよう変更されました。 このような状況で、`statx()`で有効なファイル作成時刻が得られなかった場合`File.birthtime`はどのように動作すべきかをこのチケットで議論いただければと思います。 このような状況で、statx()で有効なファイル作成時刻が得られなかった場合File.birthtimeはどのように動作すべきかをこのチケットで議論いただければと思います。