doctree icon indicating copy to clipboard operation
doctree copied to clipboard

パターンマッチのドキュメントを ruby/ruby の rdoc を翻訳する形で追加

Open sanfrecce-osaka opened this issue 2 years ago • 7 comments

翻訳元の原文

  • pattern_matching.rd
    • cf. https://github.com/ruby/ruby/blob/v3_2_0/doc/syntax/pattern_matching.rdoc
  • control.rd
    • cf. https://github.com/ruby/ruby/commit/281b3500580f9ec93ee17679c648eaeb4a47f8b6

pattern_matching.rd の配置に関して

rurema/doctree の refm/doc/spec 配下と ruby/ruby の doc/syntax 配下が似たようなファイル構成になっているため、 pattern_matching.rd も refm/doc/spec に配置しました また今後可能なら doc 配下のファイルやクラス・モジュール・ライブラリのヘッドラインに rdoc へのリンクを追加したいと思っていて、その場合にディレクトリ・ファイル構成を ruby/ruby に寄せておくほうが実装しやすいのではという思惑もあります

翻訳の方針

  • 翻訳する際、原文は対応箇所を把握しやすくするため bitclust のコメント機能を使って残しています
  • unpack という単語は Python に「アンパック」という用語があるのでとりあえずそのまま「アンパック」と訳しています
    • cf. https://docs.python.org/ja/3/tutorial/datastructures.html#tuples-and-sequences
  • パターンの名称にアルファベットが含まれる場合は頭文字大文字で統一しています
  • respond to に関しては「実装もオブジェクト自体が持つ」のと「応答できる」だと意味が異なり、どのように翻訳するか迷ったんですが注記を追加し Object#respond_to? へのリンクを追加することで respond to の意味での『〜を持つ』だということを説明してみました
  • rest に関しては rest parameter の日本語名に合わせて「残余」と訳しました
    • cf. https://secret-garden.hatenablog.com/entry/2022/03/11/210246
    • ただ「残余」とだけ書かれていても分かりづらいため、カッコつきで rest も併記してみました
  • Ruby 3.2 ではおそらくこの節は不要ですがまだ ruby/ruby 側でマージされていないため分岐は入れていません
    • cf. https://github.com/ruby/ruby/pull/7052
  • bitclust で利用できないタグや装飾は以下のように置き換えています
    • code タグ => 二重かぎ括弧(『』)
    • _em タグ (イタリック体) => かぎ括弧(「」)
    • + (タイプライター体) => 削除

やっていないこと

  • バージョンごとの差分の反映
    • 一旦このプルリクエストでは対応していません
    • 別途プルリクエストを出すつもりですが、デプロイの際に各バージョンごとの対応が必須ならこのプルリクエスト内で対応します 🙇

挙動確認方法

レビュー時に挙動確認する場合、以下の手順で実行してください

  • bitclust update で利用される BitClust::RRDParser#parse_level1_header が Ruby の定数が前提になっているため doc 配下のファイルに対して利用できない
  • なので bitclust setup でデータベースを更新するしかない
  • ただし、bitclust setup はローカルの rurema/doctree のソースコードを指定できないのでローカルに rurema/bitclust を clone してきて lib/bitclust/subcommands/setup_command.rb を以下のように修正してください
          @update = true
+         @doctreedir = nil
          @parser.banner = "Usage: #{File.basename($0, '.*')} setup [options]"
          @parser.on('--no-update', 'Do not update document repository') {
            @update = false
          }
+         @parser.on('--doctreedir=DOCTREE_DIR_PATH', "doctree's path") {|path|
+           @doctreedir = path
+         }
        def prepare
          home_directory = Pathname(ENV["HOME"]).expand_path
          config_dir = home_directory + ".bitclust"
          config_dir.mkpath
          config_path = config_dir + "config"
-         rubydoc_dir = config_dir + "rubydoc"
+         rubydoc_dir = !!@doctreedir ? Pathname(@doctreedir).expand_path : (config_dir + "rubydoc")
          @config = {

上記の修正は別途 rurema/bitclust にプルリクエストを投げる予定です 🙇

  • 以下の環境変数とオプションを指定して bitclust setup を実行してください
    • 必須: BITCLUST_PATH でローカルに clone してきた bitclust のパス
    • 任意: HOME.bitclust を生成するパス
    • 必須: --doctreedir でデータベース生成の際に使用する doctree のパス
    • 任意: --no-update
      • これを指定しないと git pull --rebase が実行されてしまうため(リモートブランチと差分がないなら指定の必要なし)

実行例

$ BITCLUST_PATH=/Users/XXX/rurema/bitclust HOME=/Users/XXX/rurema/doctree bundle exec bitclust setup --doctreedir=/Users/XXX/rurema/doctree --no-update
  • bitclust staticfile で挙動を確認
    • bitclust htmlfile はタイトルが Ruby の定数でない場合に (uninitialized) になったり目次のリンクのテキストが id での表記になってしまうため doc 配下の修正である今回はおすすめしません 🙏
    • このとき BITCLUST_PATHHOMEbitclust setup で指定したものと同じものを指定してください

実行例

$ BITCLUST_PATH=/Users/XXX/rurema/bitclust HOME=/Users/XXX/rurema/doctree bundle exec bitclust --target=3.1.0 statichtml -o ./output

申し送り事項

ruby-jp でメッセージを頂いた shuichi さんから Suggested Change の形でこのプルリクエストに翻訳修正の提案があるかと思います 🐱

cf. https://ruby-jp.slack.com/archives/CLQUG7B3M/p1672641969966319?thread_ts=1668382164.602709&cid=CLQUG7B3M

sanfrecce-osaka avatar Jan 02 '23 22:01 sanfrecce-osaka

@sanfrecce-osaka ありがとうございます!

幾つかの観点でsugesstionさせていただきたいのですが、まずは、議論したいところについて投稿します。 方針が決まったら、それに沿ったsuggestionを投げさせていただきたいです。

議論したいこと

「翻訳の方針」に記載いただいた項目に関して

  1. respond to foobarのような部分は、「foobar メソッドを持つオブジェクト」「オブジェクトに foobar メソッドを定義する」と直接的に表現するのはどうだろうか(そして注釈を削除し、respond toの香りを無くす)

    • respond toをあまり大事にする必要がないと思うため:
      • トレイトやインターフェイスのないRubyでは、ダックタイピング的に実装することになるが、そこまでくると、直接的に「メソッドを持つ」でいいと感じる
      • ココをうまく使いこなすのに、内部の挙動であるObject#respond_to?まで踏み込んで理解する必要性は薄く(個人的見解)、却って(初心者寄りの読者は特に)混乱を招きそう
  2. rest(**)の日本語訳は、もう少しわかりやすい用語を検討してもいいかもしれない

    • JavaScript/TypeScriptドキュメントの、rest parameter(引数)の日本語訳「残余引数」から来ているだけな気がする
      • 特にRubyの文脈では、「残余」と表現しているネット上の文献は、殆どない印象
        • 記載いただいたブログか、 https://qiita.com/pink_bangbi/items/f85456db344b468ef758 くらい?(ただし後者は、引数のrest parameterの日本語訳として;これもJS/TS由来の翻訳かもしれない)
      • 他の言語はうまく見つけられなかった(Schemeなどはちょこっと見かけた)
    • るりまや、Ruby公式のニュースでは、rest parameterを「rest引数」としている
      • るりま:https://docs.ruby-lang.org/ja/latest/doc/spec=2fdef.html
      • Ruby公式のニュース:https://www.ruby-lang.org/ja/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/
    • ...ので、一案として、**は「rest変数」でもいいかも?

その他

  1. 未定義の用語である、カタカナ「サブパターン」は避けたい

    原文中で『sub-pattern』としているところは、具体的にArrayパターン、Findパターン、Hashパターンの構文で指定されている<subpattern>の場所そのものを指していると思われるが、これをどう翻訳するか。 具体的には、プルリクファイル「refm/doc/spec/pattern_matching.rd」の312, 393, 506行目らへんなど。

    私の、この「<subpattern>の場所そのものを指していると思われる」が正しいと仮定して...

    • カタカナで『サブパターン』とすると、原文と違い、字面が別物なので「パターン構文のあの場所に相当するところかぁ」という気持ちにならない。説明なく現れて消える用語になってしまい、混乱するので、使用を避けたい
    • 文脈的に、「構文部分の<subpattern>のことだね、ウンウン」を意識する必要性自体は薄そう(「まあ、マッチに使うパターンの部分のことやろ」と察せられる)
    • 変更案(例)
      • いっそ、全部バッサリ「パターン(部分)」などにしてしまう
      • 丁寧に...312, 393行目は本文中で余裕もあるので、「サブパターン(Array/Find/Hashパターン構文の<subpattern>の部分)」とし、506行目はコードコメントなので「パターン」にする
  2. 用語『束縛』に対しては、「(Rubyでは)代入と読み替えていいよ」という注釈をつけるか、いっそ『代入』に書き換えるか、をした方が親切に思う

    • 個人的には、パターンマッチの文脈で他の言語に触れた際の『束縛』に橋渡しできるので、注釈を一発入れて『束縛』という用語は残していいかも
  3. 『unpack』は、わかりやすい日本語をひねり出せたら嬉しい

    • 例えば、「値を取り出す(unpacking)」など...?(あまり深く考えてないです)

shu-i-chi avatar Jan 04 '23 05:01 shu-i-chi

次に、その他の変更提案を投稿します。それぞれについて、この後suggestionをそれぞれあらかじめ投げます。もし問題ないと感じるものであれば、それぞれacceptいただけますと幸いです。

その他変更提案

るりまの他のページに表現をあわせる

  1. FooBarErrorがraiseされる -> 例外FooBarErrorが発生する
  2. カッコ -> 括弧
  3. key -> キー(ハッシュの文脈で)
  4. マッチング -> マッチ
    • 一例:https://docs.ruby-lang.org/ja/latest/doc/spec=2fregexp.html#str

      特別な文字列に対するマッチ

    • Regexp#matchでは「マッチング」になっているが...全体的には、マッチングとされそうなところでも「マッチ」が使われている印象(https://docs.ruby-lang.org/ja/latest/method/Regexp/i/match.html)

shu-i-chi avatar Jan 05 '23 10:01 shu-i-chi

@sanfrecce-osaka さん 残り、

  • [x] コードコメント部分の全体的な変更提案
  • [x] 訳がないところへの提案
    • [x] コードコメント部分
    • [x] 本文 -> 対象なし
  • [x] ここはこういう意味ではないでしょうか提案
    • [x] コードコメント部分
    • [x] 本文
  • [ ] 日本語こうしたほうがわかりやすいのではないか、どうでしょうか提案
  • [ ] ここは原文にプラスしてこう補足したいです提案
    • [x] コードコメント部分
    • [ ] 本文

があるのですが、ここまでの「議論したいこと」「その他変更提案」とダブる箇所も一部ある=suggestionがコンフリクトしちゃう?ため、まだ投下しません。 一旦、ここまでのsuggestionをご確認いただきたいです!(既存提案の処遇決定後に、残りを投下していくつもりです。)

shu-i-chi avatar Jan 05 '23 11:01 shu-i-chi

「こいつ、いつまで変更提案出してくるんだ...」と感じられると思うので、進捗チェック表をここに共有させてください。

変更提案進捗

  • [x] コードコメント部分の全体的な変更提案
  • [x] 訳がないところへの提案
    • [x] コードコメント部分
    • [x] 本文 -> 対象なし
  • [x] ここはこういう意味ではないでしょうか提案
    • [x] コードコメント部分
    • [x] 本文
  • [ ] 日本語こうしたほうがわかりやすいのではないか、どうでしょうか提案
  • [ ] ここは原文にプラスしてこう補足したいです提案
    • [x] コードコメント部分
    • [ ] 本文

議論したいこと

  • [x] 1. respond to foobarの表現について 「foobar メソッドを持つオブジェクト」「オブジェクトに foobar メソッドを定義する」と直接的に表現&注釈を削除し、respond toの香りを無くしてはどうか

    • [x] どうするか
    • [x] 変更提案(する場合)
  • [ ] 2. rest(**)の、、もっとわかりやすい日本語訳はないかしら

    • [ ] 検討結果
    • [ ] 変更提案(する場合)
  • [x] 3. 未定義の用語である、カタカナ「サブパターン」は避けたい

    • [x] 検討結果
    • [x] 変更提案(する場合)
  • [ ] 4. 用語『束縛』に対しては、「(Rubyでは)代入と読み替えていいよ」という注釈をつけるか、いっそ『代入』に書き換えるか

    • [ ] 検討結果
    • [ ] 変更提案(する場合)
  • [ ] 5. 『unpack』は、わかりやすい日本語をひねり出せたら嬉しい

    • [ ] 検討結果
    • [ ] 変更提案(する場合)

shu-i-chi avatar Jan 06 '23 17:01 shu-i-chi

@shu-i-chi

大変遅くなりました 🙏 先に 議論したいこと に対して返信します 🐶

  1. respond_to に関して

提案いただいた方針で修正しようと思います 🚀

  1. rest に関して
  1. rest(**)の日本語訳は、もう少しわかりやすい用語を検討してもいいかもしれない

    • JavaScript/TypeScriptドキュメントの、rest parameter(引数)の日本語訳「残余引数」から来ているだけな気がする

      • 特にRubyの文脈では、「残余」と表現しているネット上の文献は、殆どない印象

        • 記載いただいたブログか、 https://qiita.com/pink_bangbi/items/f85456db344b468ef758 くらい?(ただし後者は、引数のrest parameterの日本語訳として;これもJS/TS由来の翻訳かもしれない)
      • 他の言語はうまく見つけられなかった(Schemeなどはちょこっと見かけた)

    • るりまや、Ruby公式のニュースでは、rest parameterを「rest引数」としている

      • るりま:https://docs.ruby-lang.org/ja/latest/doc/spec=2fdef.html
      • Ruby公式のニュース:https://www.ruby-lang.org/ja/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/
    • ...ので、一案として、**は「rest変数」でもいいかも?

rest変数 という案をいただいたんですが、以下のようにパターンとしてはマッチさせるけど変数への束縛は行わないケースもあるので 変数 といっていいのかは迷いがあります 🐈 restパターン とかはありかと一瞬思ったんですが公式(rdoc) に「パターン」として記載されていないものをパターンと呼称するのはどうなのかという気もしていてまだ回答は出てないです 🙏

case { a: 1, b: 2 }
in { a:, ** } then p a # この節にマッチする
in { a:, b: } then p a, b
end
# => 1
  1. サブパターンに関して

提案いただいた方針で修正しようと思います 🚀

  1. 束縛に関して

「(Rubyでは)代入と読み替えていいよ」

とあるんですがこれは

「(Rubyでは 値の束縛といいつつ再代入ができるので )代入と読み替えていいよ」

という解釈で合っていますか? 👀

  1. unpack に関して

今のところ他に思い浮かばず提案頂いた「値を取り出す」がいいかなぁと思いつつ、もう少し考えさせてください 🙏

sanfrecce-osaka avatar Jan 30 '23 12:01 sanfrecce-osaka

@sanfrecce-osaka ご回答いただきありがとうございます🙏

議論したいところに書かせていただいたところのうち、残っているところについて返信させていただきます:

2. rest

2-1. 議論対象の整理

ここ、改めて見直して気づいたのですが、議論の対象は「**」のみではなく、正確には:

  • Arrayパターンにおける*
  • Hashパターンにおける**

でした...すみません💦

(原文の該当箇所――プルリクのファイルですと183行目辺り――を引用します)

Both array and hash patterns support "rest" specification:

  case [1, 2, 3]
  in [Integer, *]
    "matched"
  else
    "not matched"
  end
  #=> "matched"

  case {a: 1, b: 2, c: 3}
  in {a: Integer, **}
    "matched"
  else
    "not matched"
  end
  #=> "matched"

2-2. 「rest変数」の訳語提案について

Findパターンの構文のところに揃えたのでした

「rest変数」の訳語ですが、これは、「パターン」項の一番最初の、パターンの種類&構文の箇条書きをしているところで、以下のようにFindパターンの構文中に「*variable」という語があり、この "variable" との兼ね合いの提案なのでした(忘れてました...)。

(原文の該当箇所――プルリクのファイルですと99, 100行目辺り――を引用します)

find pattern: <code>[*variable, <subpattern>, <subpattern>, <subpattern>, ..., *variable]</code>; (<em>Find pattern</em>)

(ここの部分、仮に『rest変数』を使うとなった場合、「*(rest変数)」というsuggestionをするつもりでした。)

「変数」と呼んで良いのか

...以下のようにパターンとしてはマッチさせるけど変数への束縛は行わないケースもあるので 変数 といっていいのかは迷いがあります 🐈 ...

case { a: 1, b: 2 }
in { a:, ** } then p a # この節にマッチする
in { a:, b: } then p a, b
end
# => 1

こちらですが、束縛自体は行っていて、その値の利用をしていないだけ...だと思っています。

そして、束縛した値を利用したい場合は、「名前付きrest変数」のようなことをすれば良い、というのが、プルリクファイルの335行目辺りで説明されている、という流れだと思っています。

(該当行の原文を引用)

The "rest" part of a pattern also can be bound to a variable:

  case [1, 2, 3]
  in a, *rest
    "matched: #{a}, #{rest}"
  else
    "not matched"
  end
  #=> "matched: 1, [2, 3]"

  case {a: 1, b: 2, c: 3}
  in a:, **rest
    "matched: #{a}, #{rest}"
  else
    "not matched"
  end
  #=> "matched: 1, {:b=>2, :c=>3}"

束縛した値を再利用できないなら、「変数」呼ばわりはどうなの(『名前付きrest変数』と呼んだものがそれじゃないの)、というのはあります...が、このあと4. 用語『束縛』についてでも言及するように、関数型言語のimmutableな変数(的なもの)を背景とした用語・表現を忠実に守るよりかは、「Ruby風の」言い換えとして、思い切って「変数」呼ばわりしちゃっていいんじゃないかなと思っています。

(全然ずれたことを言っていたらすみません💦)

Findパターンの*variableと同じものなのそもそも?

(一応言及)本文中では、Arrayパターンの*とHashパターンの**を中心に説明されていますが、Findパターンでも以下のように、同様の動作をする(前後の値を束縛して、かつ名前を付けると利用できる)ことが確認できます:

case ["a", 1, "b", "c", 2]
in [*foo, String, String, *bar]
  puts "foo: #{foo}, bar: #{bar}"
else
  puts "not matched"
end
#=> foo: ["a", 1], bar: [2]

2-3. 訳語「restパターン」について

restパターン とかはありかと一瞬思ったんですが公式(rdoc) に「パターン」として記載されていないものをパターンと呼称するのはどうなのかという気もしていてまだ回答は出てないです 🙏

@sanfrecce-osaka さんと同じ理由で、私も「restパターン」は避けたほうがいいかなと感じます。

(念のため)プルリクファイル528行目で次のようなsuggestionを以前出させていただいて、取り込んでいただいています:

『**rest』 パターンが使われた場合には、keys の値として nil が渡されます。

が、ここに関してはdeconstruct_keysメソッドの引数keysの動きの話をしている文脈で、コード例も直後にあり、「やや、新しいパターンかい?」という誤解は生みづらいかなぁと思っています。

4. 用語『束縛』について

「(Rubyでは)代入と読み替えていいよ」

とあるんですがこれは

「(Rubyでは 値の束縛といいつつ再代入ができるので )代入と読み替えていいよ」

という解釈で合っていますか? 👀

そう...なのですが、私の大元の意図の記載について言及し忘れておりまして、このパターンマッチのドキュメントは、「特に他のプログラミング言語の知識がないRubyユーザが読んでも理解できるドキュメント」であるべきかなぁと考えておりました。

となったときに、「関数型言語のimmutableな変数(らしきもの)に代入(らしきことをする)動作」と詳しく対応させる&そのためにそれらの言語を知る必要性を、前提に置くことなしに、読めてほしいなと思います。

また、Rubyに置き換える際には、言語の仕組みが違うので、正確に1対1の用語の射影はできない=いわゆる妥協をする必要があると思っています。

...ということを込めて、

「『束縛』は、パターンマッチの輸入元である関数型言語なんかの用語で、ここでも使っているんだけども、(Rubyでは)代入と読み替えていいよ」

というのは、

「『束縛』は、パターンマッチの輸入元である関数型言語なんかの用語で、ここでも使っているんだけども、(ここで『束縛』って初耳です、なぁにそれ、という方々、細かいことは考えなくていい!)『束縛』は(Rubyでは)代入と読み替えていいよ (勿論、ホントは関数型言語における『束縛』との比較などの細かい話はあるけれども、だ)

みたいな意味合いでした...😅

(私の場合、Lispや不慣れなHaskellの知識ぐらいしかないので、ここで言っていることが頓珍漢な可能性があります;Lispは『関数型言語』の文脈で出すべきかはアレですが)

5. unpack に関して

今のところ他に思い浮かばず提案頂いた「値を取り出す」がいいかなぁと思いつつ、もう少し考えさせてください 🙏

私も、まだいい表現が思い浮かんでおりません......

shu-i-chi avatar Feb 13 '23 18:02 shu-i-chi

@shu-i-chi

だいぶ期間が空いての返信ですみません 🙏

  1. rest

考えてみると英文故にダブルクォーテーションで囲っているだけであまり大きな意味はなく訳す場合は単に「残りの」と訳せば良い気がしてきたのですがどうでしょう? 👀

  1. 用語『束縛』について

d261348 で対応してみました〜 😸

  1. unpack に関して

Gem::Installer#unpack で「展開」という単語が使われているのでこれでどうでしょう? 😺

https://docs.ruby-lang.org/ja/3.1/method/Gem=3a=3aInstaller/i/unpack.html

与えられたディレクトリに Gem を展開します。

sanfrecce-osaka avatar Jun 02 '23 13:06 sanfrecce-osaka

マージしました!

まあ何か問題があったらまた修正しましょう。

ohai avatar May 31 '24 11:05 ohai