ruby/docs.ruby-lang.org

class Symbol のドキュメントが別のclassのものになっている

ysakasin opened this issue · 27 comments

ruby/rdoc の不備なのか、 docs.ruby-lang.org の不備なのかわからなかったので、とりあえずこちらに報告します。

問題点

class Symbol のドキュメントが別の class のものになっており、正しいドキュメントが表示されない。

https://docs.ruby-lang.org/en/2.4.0/Symbol.html → Bignumのドキュメント
https://docs.ruby-lang.org/en/trunk/Symbol.html → Integerのドキュメント

他の症状

検索時に2つ候補が出てくる。どちらをクリックしても、間違ったドキュメントの文面が出てくる
2017-09-25 13 24 59

原因?

class Symbol のドキュメントは symbol.c ではなく string.c に記述されている。

https://github.com/ruby/ruby/blob/5d12e826475b859649f113638066b42f21b7784f/string.c#L9962

他のドキュメントサイト

ruby-docでは正しいドキュメントが表示できている
http://ruby-doc.org/core-2.4.2/Symbol.html

手元の Dash for macOS では正しいドキュメントが表示できている

okkez commented

たしかにおかしいですね。タイトルはSymbolなのに中身がBignumやIntegerになっていますね。

@sho-h チェックしてもらってもいいでしょうか?

sho-h commented

@okkez はいー。

@NKMR6194 大変有益な切り分け情報含めありがとうございます!

#36 で作業中のvagrant環境で生成する分には同じ状態になりました。とりあえず 5730273 の修正の影響か気になったのでそれだけrevertして生成しましたが同じ状態でした。

教えていただいてる切り分けの結果からは有り得なさそうですが、document-classが間違ってるものはなかったです(確認したのはtrunkのみ)。

$ find . -type f | xargs grep -i 'document-class: symbol'
(string.cが引っかかるが、Symbolの定義はstring.cにあるので問題ない)

ruby-doc.orgの生成方法がわかるようなら、後でRakefileのrdoc:en/<ver>タスクと比較してみたいと思います。あとrdocだけ更新して直るとかであれば調査は途中でも一旦適用することを提案するかもしれません。

下記のように実行したところ、期待する内容の Symbol.html が生成されました

bundle exec rake source:2.4.0
bundle exec rake rdoc:en/2.4.0

ログ

[sakasin@mac ~/src/docs.ruby-lang.org] (master=)$ bundle exec rake source:2.4.0
git clone --depth=1 --branch=ruby_2_4 git://github.com/ruby/ruby.git sources/2.4.0
Cloning into 'sources/2.4.0'...
remote: Counting objects: 3771, done.
remote: Compressing objects: 100% (3484/3484), done.
remote: Total 3771 (delta 167), reused 1334 (delta 116), pack-reused 0
Receiving objects: 100% (3771/3771), 10.87 MiB | 5.44 MiB/s, done.
Resolving deltas: 100% (167/167), done.
[sakasin@mac ~/src/docs.ruby-lang.org] (master=)$ bundle exec rake rdoc:en/2.4.0
Parsing sources...
100% [879/879]  sources/2.4.0/vsnprintf.c                                                                           

Generating Darkfish format into /Users/yasuhiro/src/docs.ruby-lang.org/2.4.0...

  Files:        879

  Classes:     1311 ( 548 undocumented)
  Modules:      271 ( 110 undocumented)
  Constants:   1271 ( 530 undocumented)
  Attributes:  1053 ( 247 undocumented)
  Methods:     9852 (2103 undocumented)

  Total:      13758 (3538 undocumented)
   74.28% documented

  Elapsed: 215.1s
[sakasin@mac ~/src/docs.ruby-lang.org] (master=)$ sed -n 314,319p 2.4.0/Symbol.html 
          <p>Compares <code>symbol</code> with <code>other_symbol</code> after calling
<a href="Symbol.html#method-i-to_s">to_s</a> on each of the symbols.
Returns -1, 0, +1 or nil depending on whether <code>symbol</code> is less
than, equal to, or greater than <code>other_symbol</code>.</p>

<pre>+nil+ is returned if the two values are incomparable.</pre>

bundle exec rake source:2.4.0
bundle exec rake compile:2.4.0
bundle exec rake rdoc:en/2.4.0

の順でも正しい Symbol.html が得られました

ログ

[sakasin@mac ~/src/docs.ruby-lang.org] (master=)$ bundle exec rake source:2.4.0
git clone --depth=1 --branch=ruby_2_4 git://github.com/ruby/ruby.git sources/2.4.0
Cloning into 'sources/2.4.0'...
remote: Counting objects: 3771, done.
remote: Compressing objects: 100% (3484/3484), done.
remote: Total 3771 (delta 167), reused 1334 (delta 116), pack-reused 0
Receiving objects: 100% (3771/3771), 10.87 MiB | 453.00 KiB/s, done.
Resolving deltas: 100% (167/167), done.
[sakasin@mac ~/src/docs.ruby-lang.org] (master=)$ bundle exec rake compile:2.4.0
(略)
compiling ./enc/trans/single_byte.c
linking transcoder single_byte.bundle
compiling ./enc/trans/utf8_mac.c
linking transcoder utf8_mac.bundle
compiling ./enc/trans/utf_16_32.c
linking transcoder utf_16_32.bundle
making encs
make[1]: Nothing to be done for `encs'.
Generating RDoc documentation
Parsing sources...
100% [887/887]  vsnprintf.c                                                                            

Generating RI format into /Users/yasuhiro/src/docs.ruby-lang.org/sources/2.4.0/.ext/rdoc...

  Files:        887

  Classes:     1311 ( 548 undocumented)
  Modules:      274 ( 110 undocumented)
  Constants:   2141 ( 559 undocumented)
  Attributes:  1053 ( 247 undocumented)
  Methods:     9830 (2099 undocumented)

  Total:      14609 (3563 undocumented)
   75.61% documented

  Elapsed: 65.1s

[sakasin@mac ~/src/docs.ruby-lang.org] (master=)$ bundle exec rake rdoc:en/2.4.0
Parsing sources...
100% [887/887]  sources/2.4.0/vsnprintf.c                                                                           

Generating Darkfish format into /Users/yasuhiro/src/docs.ruby-lang.org/2.4.0...

  Files:        887

  Classes:     1311 ( 548 undocumented)
  Modules:      273 ( 110 undocumented)
  Constants:   2141 ( 559 undocumented)
  Attributes:  1053 ( 247 undocumented)
  Methods:     9866 (2105 undocumented)

  Total:      14644 (3569 undocumented)
   75.63% documented

  Elapsed: 208.6s

[sakasin@mac ~/src/docs.ruby-lang.org] (master=)$ sed -n 314,319p 2.4.0/Symbol.html
          <p>Compares <code>symbol</code> with <code>other_symbol</code> after calling
<a href="Symbol.html#method-i-to_s">to_s</a> on each of the symbols.
Returns -1, 0, +1 or nil depending on whether <code>symbol</code> is less
than, equal to, or greater than <code>other_symbol</code>.</p>

<pre>+nil+ is returned if the two values are incomparable.</pre>
sho-h commented

@NKMR6194 おぉ、助かります!ちなみにですがこの時のRubyとrdocのバージョン教えていただいていいですか?

@sho-h 以下の通りです

[sakasin@mac ~/src/docs.ruby-lang.org] (master=)$ ruby --version
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-darwin16]
[sakasin@mac ~/src/docs.ruby-lang.org] (master=)$ bundle exec rdoc --version
5.1.0

compile時にriを生成していたので気になって見てみたのですが、ヘンテコなことになっていました。

Integer と BigDecimal のドキュメントが含まれています。

= Symbol < Object

------------------------------------------------------------------------------
= Includes:
Comparable (from
/Users/sakasin/src/docs.ruby-lang.org/sources/2.4.0/.ext/rdoc)

(from /Users/sakasin/src/docs.ruby-lang.org/sources/2.4.0/.ext/rdoc)
------------------------------------------------------------------------------

Symbol objects represent names and some strings inside the Ruby interpreter.
They are generated using the :name and :"string" literals syntax, and by the
various to_sym methods. The same Symbol object will be created for a given
name or string for the duration of a program's execution, regardless of the
context or meaning of that name. Thus if Fred is a constant in one context, a
method in another, and a class in a third, the Symbol :Fred will be the same
object in all three contexts.

  module One
    class Fred
    end
    $f1 = :Fred
  end
  module Two
    Fred = 1
    $f2 = :Fred
  end
  def Fred()
  end
  $f3 = :Fred
  $f1.object_id   #=> 2514190
  $f2.object_id   #=> 2514190
  $f3.object_id   #=> 2514190

BigDecimal extends the native Integer class to provide the #to_d method.

When you require the BigDecimal library in your application, this method will
be available on Integer objects.

Add double dispatch to Integer

When mathn is required, Integer's division is enhanced to return more precise
values from mathematical expressions.


  2/3*3  # => 0
  require 'mathn'
  2/3*3  # => 2

  (2**72) / ((2**70) * 3)  # => 4/3



Holds Integer values.  You cannot add a singleton method to an Integer. Any
attempt to add a singleton method to an Integer object will raise a TypeError.
------------------------------------------------------------------------------
= Constants:

GMP_VERSION:
  The version of loaded GMP.



= Class methods:

  all_symbols, each_prime, from_prime_division, json_create

= Instance methods:

  %, &, *, **, +, -, -@, /, <, <<, <=, <=>, ==, ===, =~, >, >=, >>, [], ^,
  abs, as_json, bit_length, capitalize, casecmp, casecmp?, ceil, chr, coerce,
  dclone, denominator, digits, div, divmod, downcase, downto, empty?,
  encoding, even?, fdiv, floor, gcd, gcdlcm, id2name, inspect, integer?,
  intern, lcm, length, magnitude, match, match?, modulo, next, numerator,
  odd?, ord, pred, prime?, prime_division, rationalize, remainder, round,
  size, slice, succ, swapcase, times, to_bn, to_d, to_f, to_i, to_int,
  to_json, to_proc, to_r, to_s, to_sym, truncate, upcase, upto, |, ~
sho-h commented

ありがとうございます!riの方はBigDecimal辺りが表示されてそうですね。うーん...

実サーバ上のRubyが2.3.3なので、以下のようにしてみると、手元では普通に生成されますが、Vagrant環境上ではそうではないですね...

local$ rbenv global 2.3.3
local$ bundle exec rdoc -v
5.1.0
local$ bundle exec rake source:2.4.0
local$ bundle exec rake rdoc:en/2.4.0
(Symbol.htmlが正常)

vagrant$ ruby -v
ruby 2.3.3p222 (2016-11-21) [x86_64-linux-gnu]
vagrant$ bundle exec rdoc -v
5.1.0
vagrant$ bundle exec rake source:2.4.0
vagrant$ bundle exec rake rdoc:en/2.4.0
(Symbol.htmlが異常)

vagrant環境の/var/www/docs.ruby-lang.org/revisions.logを見るに、1488692(本日時点では最新) のため、localとvagrantに差異はないはず...。

bundle exec rake rdoc を実行して中断した後に bundle exec rake rdoc:en/trunk したところ不正な Symbol.html がローカルでも再現しました

おそらく条件は 「 source 以下に複数のソースがあって、それらがコンパイルされていること」 のように思えます。

複数 source があるだけだと再現しませんでした。

また、trunkと2.4.0のリポジトリのみがsourceにあり、どちらもコンパイルされている状態では bundle exec rake rdoc:en/trunk のみが不正なSymbol.html を生成しました

sho-h commented

おぉ、再現すごい。

実は実機だとautoconfとbisonがなくてコンパイルの最初の方で失敗してるようなので、コンパイルは影響を及ぼせてなさそうです。「source 以下に複数のソースがあって、」の後はもう少し変わってくるかもしれません。

一方こちらでは、実機がDebianのため手元と実機で差分があるのかしら?とパッケージにあたってるパッチを見てみるなどしましたが、今のところ実りはありません。気になる修正はnormalized_file_listに対して以下のようなパッチがDebianパッケージのRubyのrdocに当たってるくらいでした。しかし、bundle installした方のrdocが使われますし、一応この修正を5.1.0のrdocに入れても動作に変化はありませんでした。(他の修正は関係ない気がする

--- ruby2.3-2.3.3.orig/lib/rdoc/rdoc.rb
+++ ruby2.3-2.3.3/lib/rdoc/rdoc.rb
@@ -321,7 +321,7 @@ option)
       end
     end

-    file_list.flatten
+    file_list.flatten.sort
   end

あとはrdocのバージョンを5.1から5.0にしても結果は変わりませんでした。

自分でも後で再現ためしてみます。

sho-h commented

しかし、時間がかかりそうですので、以下のような一次対応をお昼頃に取ろうかと思います。

  • 直接再生成して置き換えるとか手元で生成して置き換える
  • rdoc向けのcronを止める
hsbt commented

rdoc のバグかな? と思い issue で記録してました... ruby/rdoc#422

そもそもの理由は rdoc の可能性もあるので、何か発見したら教えてください。

sho-h commented

PRチャンスキタコレ!(報告了解ですー

上のDebianパッケージのみのrdoc 4.2.1にsortを追記するパッチ、rdocのmasterでは取り込まれてなさそうなのは気になってて(といっても同じ修正をしても改善しなかったので別の場所か問題が存在しないかですが)、rdocを真面目に追いかけないといけない気はしています。

sho-h commented

まとめて生成してみる。-> 確かに再現した。

$ (bundle インストールし直ししたりソース消してクリーンにする)
$ for version in 2.2.0 2.3.0 2.4.0 trunk; do
    bundle exec rake update:${version}
    bundle exec rake rdoc:clobber_en/${version}
    bundle exec rake rdoc:en/${version}
  done

あららと言うことで個別に。汚いけど以下のようにしてはソース消し消ししながらやったが結局どれかがうまく生成できてない感じなので置き直しもちょっと難しそう。

$ (クリーンに(ry
$ v=2.2.0 && bundle exec rake update:${v} && bundle exec rake rdoc:clobber_en/${v} && bundle exec rake rdoc:en/${v}
$ v=2.3.0 && bundle exec rake update:${v} && bundle exec rake rdoc:clobber_en/${v} && bundle exec rake rdoc:en/${v}
$ v=2.4.0 && bundle exec rake update:${v} && bundle exec rake rdoc:clobber_en/${v} && bundle exec rake rdoc:en/${v}
$ v=trunk && bundle exec rake update:${v} && bundle exec rake rdoc:clobber_en/${v} && bundle exec rake rdoc:en/${v}

条件として見てるものが置き換わってないだけで必ず何かが問題になるのかもしれない。

下記の環境で Ruby 2.4.2 と 2.2.8 の tar.gz を落として来てrdocしてみたのですが、どちらも不正なSymbol.htmlが出力されてしまいました……

sinji@sakasin:~$ ruby --version
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]
sinji@sakasin:~$ rdoc --version
5.0.0
sinji@sakasin:~$ cat /etc/debian_version
8.9

実行したコマンド

sinji@sakasin:/tmp$ rdoc ruby-2.4.2 -o rdoc-ruby-2.4.2

(PRチャンスを生かしたい……)

sho-h commented

原因は後述ですが顕在化してるのはlib/rdoc/ruby_token.rbに以下の行があるせいでした。

module RDoc::RubyToken
  ...
  # for ruby 1.4X
  if !defined?(Symbol)
    Symbol = Integer
  end

以下記録です。(整形とかはちょっと諦めて手元のメモを単にペタリ

再現したのでrdoc/generator/darkfish.rbでHTML生成するところ(generate_class_filesのcurrent = nilの次の行)でbinding.irbを仕込んで確認。

> @classes.select {|c| c.name == 'Symbol'}.count
2 # 2個はまずい
> symbols = @classes.select {|c| c.name == 'Symbol'}
> symbols.first # 問題なさそう
<RDoc::NormalClass:0x3ff2897866d8 class Symbol < Object includes: [#<RDoc::Include:0x3ff28988320c Symbol.rdoc::include Comparable>] extends: [] attributes: [] methods: [..., #<RDoc::AnyMethod:0x3ff28d8c0e14 Symbol::all_symbols (public)>, ...
> symbols.last # 問題あり
<RDoc::NormalClass:0x3ff28d8d9be4 class Symbol < Numeric includes: [] extends: [] attributes: [] methods: [#<RDoc::AnyMethod:0x3ff2891ee9dc Integer#to_d (public)>, ...

これだとその下で以下のような内容のため、Symbolが後の方で上書きされそうな感じ。

@classes.each do |klass|
  generate_class klass, template_file
end

いっぽうrdoc/parser/c.rbに仕込むと1回のみirbが立ち上がる。

    ...
+   binding.irb if cm.name == 'Symbol'
    cm.record_location enclosure.top_level

内容はただしそう。なお、cmはdarkfishのところでも出たRDoc::NormalClass。

> @content.lines.grep /rb_define_method/
[..., "    rb_define_method(rb_cSymbol, \"encoding\", sym_encoding, 0);\n"]

という事で間のどこかでバラバラになってそう。

rdoc/store.rbのall_classes_and_modulesの直後に仕込む。

> @classes_hash.keys.first
"Array"
> syms = @classes_hash.select {|key, cm| cm.name == 'Symbol'}
> syms.count
2
> syms.keys
["Symbol", "RDoc::RubyToken::Symbol"]

もしやなにかモジュールの下にあるクラスがSymbolという名前で定義されてる?

lib/rdoc/ruby_token.rbをみると以下があやしい。

module RDoc::RubyToken
  # :stopdoc:

  EXPR_BEG = :EXPR_BEG
  EXPR_MID = :EXPR_MID
  EXPR_END = :EXPR_END
  EXPR_ARG = :EXPR_ARG
  EXPR_FNAME = :EXPR_FNAME
  EXPR_DOT = :EXPR_DOT
  EXPR_CLASS = :EXPR_CLASS

  # for ruby 1.4X
  if !defined?(Symbol)
    Symbol = Integer # <= ここが問題?
  end

1.4向けのコードを削除して生成し直したところ、問題なく生成できた。
(合ってるとしたらruby-doc.orgが生成するのに使ってるのはなにか影響を受けないバージョン?

という事は3つくらい問題がある気がする。

  1. stopdocにもかかわらず読んでる(事情あり?たぶん出力はしてないのだろう)
  2. RDoc::NormalClassのnameを読む処理に問題がある
    • RDoc::Storeの@classes_hashでkeyはただしいのでnameだけ
  3. 上の1.4向けのコードが不要

1.か2.がどこかでリグレッションして昔OK、今NGという具合だと想像した。binding.irb最高だった。

sho-h commented

とりあえず3.だけPRしましたが、似たような定義がRuby本体に存在する場合は同じ問題が出たりでなかったりする(たまたまどちらが最後に読まれたかで決まると想像しています)ので、2.もPRしておきたいところです。

原因がわかったため、再生成案が復活できるので明日の午前中にでもSymbol.htmlだけ置き換えます。(影響を受けるファイルを消して生成すれば良いことがわかった)

しかし、今日の昼Integer.htmlがおかしいと思って諦めたあれは正しかったのか...2.4で大きく変わってて予期せず置き換わってると勘違いしたのかしら?

sho-h commented

という事でSymbol.htmlだけ手で置き換えます。

(全部消した後で再bundle installと再clone
local$ bundle install -path ...
local$ for version in 2.2.0 2.3.0 2.4.0 trunk; do
    bundle exec rake update:${version}
  done

cloneしたruby_token.rbから該当のコードを削除して生成。Symbol.htmlだけ直接置き換えました。

$ for version in 2.2.0 2.3.0 2.4.0 trunk; do
    bundle exec rake rdoc:clobber_en/${version}
    bundle exec rake rdoc:en/${version}
  done

あとは以下の作業があるので別Issueにしたりしながら作業します。(思いついたら直接足していく可能性あり

  • rdocが更新されたら評価して採用するか決める
    • 5.1.0と6.0.0の成果物をdiff -urするなど
  • docs.ruby-lang.orgでrdocの更新を反映する
  • rdocのcronを再開する
sorah commented

ガッと 6.0.0.beta2 にしちゃってもいいのかなとは思った。

sorah commented

…というのも、6.0.0.beta2 をさっさと巨大な RDoc であるところの docs.r-l.o で試しておけば、問題点とか正式リリース前に判明するんじゃないかなあと。丁寧に評価する必要性はそんなに無いと思うんですが、どうでしょうね…。

cc @aycabta

sho-h commented

なるほどって思ったのでいいのではないかとおもいます!

sho-h commented

参考までに5.1.0と6.0.0.beta2で比較です。

$ (生成)
$ diff -ur --brief trunk.5.1.0 trunk.6.0.0.beta2 | grep 'Only in'
Only in trunk.5.1.0/Gem: RbConfig.html
Only in trunk.5.1.0/Net: InternetMessageIO
Only in trunk.5.1.0/Net: InternetMessageIO.html
Only in trunk.5.1.0/Net: Socket.html
Only in trunk.6.0.0.beta2/Net: WriteAdapter.html

以下が見れなくなるが特に中身がないので問題ない。わざとかも。

一方で以下が差分があるのかもしれないので、その内追いかけて必要ならIssueにする。

中身は #43 を反映してぎゃっとなってから頑張って追いかけるつもりです。となると cron もさっさと再開して本Issueはcloseしてしまえばいいかも。

sorah commented

順次 6.0.0 で再生成中。trunk は終わった https://docs.ruby-lang.org/en/trunk/index.html

cron 再開もやっておきます。@sho-h さんに適当に見てもらって close かな。問題あったら別 issue にしましょう。

The Gem::RbConfig doesn't exist namespace and it fixed before RDoc 6.

The Net::Socket exists clearly, so it's bug that haven't been known. I guess that the reason for it is CRuby source code has many Socket class and it causes the behavior. I filed a issue at ruby/rdoc#534.

The Net::InternetMessageIO has :nodoc: and it fixed before RDoc 6.

The Net::WriteAdapter is correct namespace for it, and the Net::InternetMessageIO::WriteAdapter is bug and it fixed before RDoc 6.

sho-h commented

@sorah 作業どもでしたー。遅くなりました。Symbol.html以外は現状特にないのでcloseしときます。Symbol.htmlの方はブランチから古いコード削除してもらうチケットをbugs.ruby-lang.orgに立てようと思います。

@aycabta Thanks! No more new problems!

@sho-h I'm checking what https://docs.ruby-lang.org/en/trunk/Net/Socket.html doesn't exist, but I couldn't. Would you please show old versions Net/Socket.html document URL or reproduction steps with Ruby version and RDoc version.

I guess that Net::Socket was bug, so I closed ruby/rdoc#534.