Ruby Issue Tracking System: Issues
https://bugs.ruby-lang.org/
https://bugs.ruby-lang.org/favicon.ico?1711330511
2019-10-02T03:50:57Z
Ruby Issue Tracking System
Redmine
Ruby master - Bug #16197 (Closed): make install under non-root user fails for Ruby 2.4.8 tarball
https://bugs.ruby-lang.org/issues/16197
2019-10-02T03:50:57Z
sorah (Sorah Fukumori)
her@sorah.jp
<p><a href="http://www.ruby-lang.org/en/news/2019/10/01/ruby-2-4-8-released/" class="external">http://www.ruby-lang.org/en/news/2019/10/01/ruby-2-4-8-released/</a></p>
<p>Ruby 2.4.8 tarball doesn't install under non-root user with the following error:</p>
<pre><code>installing bundle gems: /usr/share/rbenv/versions/2.4.8/lib/ruby/gems/2.4.0 (build_info, cache, doc, extensions, gems, specifications)
/usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package.rb:383:in `initialize': Permission denied @ rb_sysopen - /usr/share/rbenv/versions/2.4.8/lib/ruby/gems/2.4.0/gems/did_you_mean-1.1.0/.gitignore (Errno::EACCES)
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package.rb:383:in `open'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package.rb:383:in `block (2 levels) in extract_tar_gz'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package/tar_reader.rb:65:in `each'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package.rb:365:in `block in extract_tar_gz'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package.rb:492:in `block in open_tar_gz'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package.rb:489:in `wrap'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package.rb:489:in `open_tar_gz'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package.rb:364:in `extract_tar_gz'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package.rb:345:in `block (2 levels) in extract_files'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package/tar_reader.rb:65:in `each'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package.rb:342:in `block in extract_files'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package/file_source.rb:30:in `open'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package/file_source.rb:30:in `with_read_io'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/package.rb:339:in `extract_files'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/installer.rb:801:in `extract_files'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/installer.rb:302:in `install'
from ./tool/rbinstall.rb:685:in `call'
from ./tool/rbinstall.rb:685:in `block in <class:Installer>'
from ./tool/rbinstall.rb:784:in `block (3 levels) in <main>'
from /usr/share/rbenv/sources/2.4.8/ruby-2.4.8/lib/rubygems/user_interaction.rb:51:in `use_ui'
from ./tool/rbinstall.rb:784:in `block (2 levels) in <main>'
from ./tool/rbinstall.rb:780:in `each'
from ./tool/rbinstall.rb:780:in `block in <main>'
from ./tool/rbinstall.rb:822:in `block in <main>'
from ./tool/rbinstall.rb:819:in `each'
from ./tool/rbinstall.rb:819:in `<main>'
make: *** [uncommon.mk:284: do-install-nodoc] Error 1
</code></pre>
<p>Release maintainers are aware of this issue and give a follow up soon.<br>
Opening this ticket for tracking the issue. I will post an update on <a href="http://www.ruby-lang.org" class="external">www.ruby-lang.org</a>.</p>
Ruby master - Feature #14141 (Closed): Add a method to Exception for retrieving formatted excepti...
https://bugs.ruby-lang.org/issues/14141
2017-11-29T09:34:19Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>Most people want to log caught exceptions to stderr (or somewhere else) then continues their program as usual.</p>
<pre><code>def the_program
# ...
raise "failure!"
# ...
rescue RuntimeError => e
$stderr.puts "#{e.message} (#{e.class})\n\t#{e.backtrace.join("\n\t")}"
retry
end
</code></pre>
<p>I'm very bored to write error logging many time...<br>
I want to log errors in the default format of Ruby, just like the following:</p>
<pre><code>rescue RuntimeError => e
e.display
# ...
</code></pre>
<p>From Ruby 2.5, we've started branching error formatting on TTY-ness of <code>$stderr</code>. It'd be bit more useful if we can log using the same format with the format which Ruby determines.</p>
<p>Ruby already has <code>Object#display</code>.<br>
One consideration is to retrieve formatted String from Exception object, but the current error logging code (eval_error.c) depends on IO,<br>
so I want to start from just having <code>Exception#display</code>. I think most use case is just to log errors into IO.</p>
Ruby master - Feature #14140 (Closed): Show exception message in bold and underline when logging ...
https://bugs.ruby-lang.org/issues/14140
2017-11-29T08:58:06Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>We're already branching error logging format for TTY and non-TTY.<br>
This patch adds bold and underline ANSI color sequence to an error log for TTY.</p>
<p><img src="https://img.sorah.jp/s/2017-11-29_1711_xj2fu.png" alt="screenshot"></p>
Ruby master - Feature #13568 (Closed): File#path for O_TMPFILE fds has no meaning
https://bugs.ruby-lang.org/issues/13568
2017-05-15T10:53:39Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>By using File::TMPFILE (O_TMPFILE) allows us to create a file without directory entries.</p>
<p>While open(2) with O_TMPFILE don't create a file without directory entries, it still requires a directory name to determine a file system to create a file.</p>
<p>Current Ruby implementation holds such directory names in fptr->pathv and retrievable via File#path.<br>
But such paths are useless and may raise errors. For example, some code <a href="https://github.com/aws/aws-sdk-ruby/blob/v2.9.17/aws-sdk-core/lib/aws-sdk-core/checksums.rb#L15" class="external">1</a> checks File#path availability then when available, it attempts to use the path to open a file in different fd, finally raises Errno::EISDIR.</p>
<p>This patch changes File#path (fptr->pathv) not to return String if a fd is opened with O_TMPFILE.</p>
Ruby master - Feature #11999 (Closed): MatchData#to_h to get a Hash from named captures
https://bugs.ruby-lang.org/issues/11999
2016-01-18T06:37:23Z
sorah (Sorah Fukumori)
her@sorah.jp
<pre><code>class MatchData
def to_h
self.names.map { |n| [n, self[n]] }.to_h
end
end
p '12'.match(/(?<a>.)(?<b>.)(?<c>.)?/).to_h #=> {"a"=>"1", "b"=>"2", "c"=>nil}
</code></pre>
<p>Sometimes I want to get a Hash from named capture, but currently I have to use #names + #captures. How about adding MatchData#to_h for convenience way?</p>
Ruby master - Feature #11049 (Closed): Enumerable#grep_v (inversed grep)
https://bugs.ruby-lang.org/issues/11049
2015-04-08T10:23:40Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>sometime I want to do <code>grep -v</code> like operation:</p>
<pre><code>%w(aaa bbb ccc).reject { |x| /b/ === x } #=> ["aaa", "ccc"]
</code></pre>
<p>We already have Enumerable#grep, so I propose to add Enumerable#grep_v.</p>
<pre><code>%w(aaa bbb ccc).grep(/b/) #=> ["bbb"]
%w(aaa bbb ccc).grep_v(/b/) #=> ["aaa", "ccc"]
</code></pre>
<a name="Naming-Interface"></a>
<h2 >Naming / Interface<a href="#Naming-Interface" class="wiki-anchor">¶</a></h2>
<p>This idea is mentioned at DevelopersMeeting20150408Japan by me. Matz has said "I don't disagree for the feature. So this remains naming (interface) problem."</p>
<p>I'm not sure grep_v is the best name for this feature; feedback are welcomed.</p>
<a name="Ideas"></a>
<h3 >Ideas<a href="#Ideas" class="wiki-anchor">¶</a></h3>
<ul>
<li>
<code>grep_v(pattern)</code> (the first patch)</li>
<li><code>grep(pattern, inverse: true)</code></li>
<li><code>grep!(pattern)</code></li>
</ul>
Ruby master - Bug #11016 (Closed): method calls without parenthesis makes SyntaxError when DVAR e...
https://bugs.ruby-lang.org/issues/11016
2015-03-30T11:02:06Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>It seems like the following situation makes SyntaxError</p>
<ol>
<li>Try to call method which same name of local variable exists, without parenthesis</li>
<li>Argument part contains colon (':')</li>
</ol>
<p>All the following test cases contain empty method definition, but it's not required (if you omit it, the expected result is NoMethodError instead of SyntaxError)</p>
<a name="ng_assocrb"></a>
<h3 >ng_assoc.rb<a href="#ng_assocrb" class="wiki-anchor">¶</a></h3>
<pre><code>def var(h); end
var = 1
var :a => :b
</code></pre>
<pre><code>ruby 2.3.0dev (2015-03-30 trunk 50121) [x86_64-darwin14]
ng_assoc.rb:3: warning: `:' after local variable or literal is interpreted as binary operator
ng_assoc.rb:3: warning: even though it seems like symbol literal
ng_assoc.rb:3: warning: possibly useless use of a variable in void context
ng_assoc.rb:3: syntax error, unexpected ':', expecting end-of-input
var :a => :b
^
</code></pre>
<a name="ng_assoc19rb"></a>
<h3 >ng_assoc19.rb<a href="#ng_assoc19rb" class="wiki-anchor">¶</a></h3>
<pre><code>def var(h); end
var = 1
var a: :b
</code></pre>
<pre><code>ruby 2.3.0dev (2015-03-30 trunk 50121) [x86_64-darwin14]
ng_assoc19.rb:3: syntax error, unexpected ':', expecting end-of-input
var a: :b
^
</code></pre>
<a name="ng_assoc19_strvaluerb"></a>
<h3 >ng_assoc19_strvalue.rb<a href="#ng_assoc19_strvaluerb" class="wiki-anchor">¶</a></h3>
<pre><code>
def var(h); end
var = 1
var a: 2
</code></pre>
<pre><code>ruby 2.3.0dev (2015-03-30 trunk 50121) [x86_64-darwin14]
ng_assoc19_strvalue.rb:4: syntax error, unexpected ':', expecting end-of-input
var a: 2
^
</code></pre>
<a name="ng_symrb"></a>
<h3 >ng_sym.rb<a href="#ng_symrb" class="wiki-anchor">¶</a></h3>
<pre><code>def var(h); end
var = 1
var :sym
</code></pre>
<pre><code>ruby 2.3.0dev (2015-03-30 trunk 50121) [x86_64-darwin14]
ng_sym.rb:3: warning: `:' after local variable or literal is interpreted as binary operator
ng_sym.rb:3: warning: even though it seems like symbol literal
ng_sym.rb:3: warning: possibly useless use of a variable in void context
ng_sym.rb:3: syntax error, unexpected ':', expecting end-of-input
var :sym
^
</code></pre>
<a name="ok_assoc19_parenrb"></a>
<h3 >ok_assoc19_paren.rb<a href="#ok_assoc19_parenrb" class="wiki-anchor">¶</a></h3>
<pre><code>def var(h); end
var = 1
var(a: :b)
</code></pre>
<pre><code>ruby 2.3.0dev (2015-03-30 trunk 50121) [x86_64-darwin14]
</code></pre>
<a name="ok_assoc_parenrb"></a>
<h3 >ok_assoc_paren.rb<a href="#ok_assoc_parenrb" class="wiki-anchor">¶</a></h3>
<pre><code>def var(h); end
var = 1
var(:a => :b)
</code></pre>
<pre><code>ruby 2.3.0dev (2015-03-30 trunk 50121) [x86_64-darwin14]
</code></pre>
<a name="ok_different_namerb"></a>
<h3 >ok_different_name.rb<a href="#ok_different_namerb" class="wiki-anchor">¶</a></h3>
<pre><code>def var(h); end
var2 = 1
var :a => :b
</code></pre>
<pre><code>ruby 2.3.0dev (2015-03-30 trunk 50121) [x86_64-darwin14]
ok_different_name.rb:2: warning: assigned but unused variable - var2
</code></pre>
<a name="ok_stringrb"></a>
<h3 >ok_string.rb<a href="#ok_stringrb" class="wiki-anchor">¶</a></h3>
<pre><code>def var(h); end
var = 1
var "str"
</code></pre>
<pre><code>ruby 2.3.0dev (2015-03-30 trunk 50121) [x86_64-darwin14]
</code></pre>
<hr>
<p>This may be another issue, but I also surprised to the following result.</p>
<pre><code>module M
class A
end
end
m = M
p m ::A #=> M::A
p M ::A #=> uninitialized constant A (NameError)
</code></pre>
Backport21 - Backport #9576 (Closed): Backport r44370 to revert Hash#reject behavior
https://bugs.ruby-lang.org/issues/9576
2014-02-28T04:29:13Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>In [Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed behind-schedule" title="Bug: Hash#reject!.size does not reflect changes to the hash (Closed)" href="https://bugs.ruby-lang.org/issues/9223">#9223</a>], naruse-san rejected incompatible change due to HashWithIndifferentAccess.</p>
<p>r44358 had changed constant name, but there was one <code>ifdef</code> condition still use old constant name.<br>
r44370 fixes it to correct one, but it's not backported to 2.1.1.</p>
<p>So HashWithIndifferentAccess in Ruby 2.1.1 is broken because Ruby 2.1.1's Hash#reject doesn't copy extra states.</p>
<ul>
<li>Commits around this change: <a href="https://gist.github.com/sorah/9265008" class="external">https://gist.github.com/sorah/9265008</a>
</li>
<li>Rails' issue: <a href="https://github.com/rails/rails/issues/14188" class="external">https://github.com/rails/rails/issues/14188</a>
</li>
</ul>
Backport200 - Backport #9175 (Closed): Backport r43913
https://bugs.ruby-lang.org/issues/9175
2013-11-29T17:59:45Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>Please backport r43913.</p>
<ul>
<li><a href="/issues/8872">[ruby-core:58606]</a></li>
<li><a href="https://github.com/rails/rails/pull/13055" class="external">https://github.com/rails/rails/pull/13055</a></li>
</ul>
Backport200 - Backport #8713 (Closed): Backport r42271
https://bugs.ruby-lang.org/issues/8713
2013-08-01T05:43:16Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>the bug fixed in r42271 is reproducible on 2.0.0</p>
Backport200 - Backport #8596 (Closed): r41734
https://bugs.ruby-lang.org/issues/8596
2013-07-02T11:39:26Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>Please backport r41734</p>
Ruby master - Bug #8595 (Closed): mkmf.rb pkg_config modifies $LDFLAGS
https://bugs.ruby-lang.org/issues/8595
2013-07-02T11:04:40Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>=begin<br>
mkmf.rb's pkg_config modifies $LDFLAGS after 2.0.0 (r35605 ?) like the following:</p>
<a name="ruby-193p392-2013-02-22-revision-39386-x86_64-linux"></a>
<h1 >ruby 1.9.3p392 (2013-02-22 revision 39386) [x86_64-linux]<a href="#ruby-193p392-2013-02-22-revision-39386-x86_64-linux" class="wiki-anchor">¶</a></h1>
<p>p $LDFLAGS #=> "-L. -rdynamic -Wl,-export-dynamic"<br>
p pkg_config('libxml-2.0') #=> ["-I/usr/include/libxml2 ", "", "-lxml2 "]<br>
p $LDFLAGS #=> "-L. -rdynamic -Wl,-export-dynamic "</p>
<a name="ruby-200p247-2013-06-27-revision-41674-x86_64-linux"></a>
<h1 >ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-linux]<a href="#ruby-200p247-2013-06-27-revision-41674-x86_64-linux" class="wiki-anchor">¶</a></h1>
<p>p $LDFLAGS #=> "-L. -fstack-protector -rdynamic -Wl,-export-dynamic"<br>
p pkg_config('libxml-2.0') #=> ["-I/usr/include/libxml2", "", "-lxml2"]<br>
p $LDFLAGS #=> "-lxml2 "</p>
<a name="200-my-patch"></a>
<h1 >2.0.0 + my patch<a href="#200-my-patch" class="wiki-anchor">¶</a></h1>
<p>p $LDFLAGS #=> "-L. -fstack-protector -rdynamic -Wl,-export-dynamic"<br>
p pkg_config('libxml-2.0') #=> ["-I/usr/include/libxml2", "", "-lxml2"]<br>
p $LDFLAGS #=> "-L. -fstack-protector -rdynamic -Wl,-export-dynamic "</p>
<p>attached patch fixes this to 1.9.3 behaviour.</p>
<p>I'll commit this if there's no problem.</p>
<p>=end</p>
Backport192 - Backport #5289 (Rejected): backport #5279 into ruby1.9.2
https://bugs.ruby-lang.org/issues/5289
2011-09-07T09:12:01Z
sorah (Sorah Fukumori)
her@sorah.jp
<p><a href="http://redmine.ruby-lang.org/issues/5279" class="external">http://redmine.ruby-lang.org/issues/5279</a></p>
<p>この問題は1.9.2でも再現するようなので,r33201 のバックポートをお願いします.</p>
Ruby master - Bug #5279 (Closed): $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある
https://bugs.ruby-lang.org/issues/5279
2011-09-06T09:39:09Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>sora_hです.</p>
<p>twitter<br>
で <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/572">@hsbt (Hiroshi SHIBATA)</a> さんがこのような事を言っていたので調査してみました:<br>
<a href="http://twitter.com/#!/hsbt/status/110700488667832320" class="external">http://twitter.com/#!/hsbt/status/110700488667832320</a></p>
<p>調査したところ,どうやらString#encodeは内部的にrequireしていて,<br>
セーフレベル3から全てのオブジェクトが汚染されるので,rb_require_safeに渡るStringが汚染されるため,<br>
rb_requireでSecurityErrorが発生します.</p>
<p>なので,以下の場合はSecurityErrorが発生しますが,</p>
<pre><code>$SAFE = 3
"a".encode("UTF-16")
</code></pre>
<p>以下の場合は発生しません.</p>
<pre><code>"a".encode("UTF-16")
$SAFE = 3
"a".encode("UTF-16")
</code></pre>
<p>これを修正するパッチを書いてみましたが(チケット末尾に貼り付け),<br>
果たしてrb_require_safeの第二引数に0を渡しても問題ないのか自信がありません.<br>
これはセキュリティ周りの問題なので,合意を取ってからコミット,もしくはパッチに<br>
含む問題を修正し合意が取れてからコミットしようと思います.</p>
<p>以下patch</p>
<p>diff --git a/ChangeLog b/ChangeLog<br>
index a16e823..07f76a7 100644<br>
--- a/ChangeLog<br>
+++ b/ChangeLog<br>
@@ -1,3 +1,8 @@<br>
+Tue Sep 6 08:56:06 2011 Shota Fukumori <a href="mailto:sorah@tubusu.net" class="email">sorah@tubusu.net</a><br>
+</p>
<ul>
<li>
<pre><code> * transcode.c: Use rb_require_safe() to load transcoder.
</code></pre>
</li>
<li>
<pre><code> Because if $SAFE is higher than 3, rb_require() raises SecurityError.
</code></pre>
</li>
<li>
</ul>
<p>Mon Sep 5 20:59:30 2011 CHIKANAGA Tomoyuki <a href="mailto:nagachika00@gmail.com" class="email">nagachika00@gmail.com</a></p>
<pre><code> * insns.def: change encoding pragma for emacs (shift_jis to utf-8).
</code></pre>
<p>diff --git a/transcode.c b/transcode.c<br>
index 2c188b6..0651aec 100644<br>
--- a/transcode.c<br>
+++ b/transcode.c<br>
@@ -375,7 +375,7 @@ load_transcoder_entry(transcoder_entry_t *entry)<br>
return NULL;<br>
memcpy(path, transcoder_lib_prefix, sizeof(transcoder_lib_prefix) - 1);<br>
memcpy(path + sizeof(transcoder_lib_prefix) - 1, lib, len + 1);</p>
<ul>
<li>
<pre><code> if (!rb_require(path))
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> if (!rb_require_safe(rb_str_new2(path), 0))
return NULL;
</code></pre>
}</li>
</ul>
Backport192 - Backport #5074 (Rejected): "[BUG] cfp consistency error - send" on TestEnumerator#t...
https://bugs.ruby-lang.org/issues/5074
2011-07-22T15:19:10Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>sora_hです。<br>
OS X Lion, 10.7.0 でtest_enumerator.rbでクラッシュします。</p>
<p>gcc --version: i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)<br>
ruby -v: ruby 1.9.4dev (2011-07-22 trunk 32614) [x86_64-darwin11.0.0]<br>
configure: ../../configure --prefix=<code>pwd</code>/local --with-readline-dir=$HOME/brew --enable-shared --enable-pthread --disable-install-doc --with-arch=x86_64 debugflags="-gdwarf-2 -g3" optflags="-O3"</p>
<p>以下ログ:</p>
<p>./miniruby -I../../lib -I. -I.ext/common ../../tool/runruby.rb --extout=.ext -- --disable-gems "../../test/runner.rb" --ruby="./miniruby -I../../lib -I. -I.ext/common ../../tool/runruby.rb --extout=.ext -- --disable-gems" -v -q ruby/test_enumerator.rb<br>
Run options: "--ruby=./miniruby -I../../lib -I. -I.ext/common ../../tool/runruby.rb --extout=.ext -- --disable-gems" -v -q</p>
<a name="Running-tests"></a>
<h1 >Running tests:<a href="#Running-tests" class="wiki-anchor">¶</a></h1>
<p>TestEnumerator#test_cons = 0.00 s = .<br>
TestEnumerator#test_feed = 0.00 s = .<br>
TestEnumerator#test_feed_before_first_next = 0.00 s = .<br>
TestEnumerator#test_feed_mixed = 0.00 s = .<br>
TestEnumerator#test_feed_twice = 0.00 s = .<br>
TestEnumerator#test_feed_yielder = /Users/sorah/git/ruby/ruby/test/ruby/test_enumerator.rb:328: [BUG] cfp consistency error - send<br>
ruby 1.9.4dev (2011-07-22 trunk 32614) [x86_64-darwin11.0.0]</p>
<p>-- Control frame information -----------------------------------------------<br>
c:0025 p:---- s:0102 b:0102 l:0014a0 d:0014a0 CFUNC :next<br>
c:0024 p:0034 s:0099 b:0099 l:0013e0 d:0013e0 METHOD /Users/sorah/git/ruby/ruby/test/ruby/test_enumerator.rb:328<br>
c:0023 p:0063 s:0093 b:0093 l:001080 d:001080 METHOD /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:948<br>
c:0022 p:0025 s:0087 b:0087 l:000086 d:000086 METHOD /Users/sorah/git/ruby/ruby/lib/test/unit/testcase.rb:17<br>
c:0021 p:0090 s:0083 b:0083 l:000071 d:000082 BLOCK /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:787<br>
c:0020 p:---- s:0077 b:0077 l:000076 d:000076 FINISH<br>
c:0019 p:---- s:0075 b:0075 l:000074 d:000074 CFUNC :map<br>
c:0018 p:0124 s:0072 b:0072 l:000071 d:000071 METHOD /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:780<br>
c:0017 p:0020 s:0064 b:0063 l:000053 d:000062 BLOCK /Users/sorah/git/ruby/ruby/lib/test/unit.rb:565<br>
c:0016 p:---- s:0059 b:0059 l:000058 d:000058 FINISH<br>
c:0015 p:---- s:0057 b:0057 l:000056 d:000056 CFUNC :each<br>
c:0014 p:0053 s:0054 b:0054 l:000053 d:000053 METHOD /Users/sorah/git/ruby/ruby/lib/test/unit.rb:563<br>
c:0013 p:0189 s:0048 b:0048 l:000047 d:000047 METHOD /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:746<br>
c:0012 p:0013 s:0038 b:0038 l:000037 d:000037 METHOD /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:909<br>
c:0011 p:0012 s:0035 b:0035 l:000026 d:000034 BLOCK /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:896<br>
c:0010 p:---- s:0032 b:0032 l:000031 d:000031 FINISH<br>
c:0009 p:---- s:0030 b:0030 l:000029 d:000029 CFUNC :each<br>
c:0008 p:0068 s:0027 b:0027 l:000026 d:000026 METHOD /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:895<br>
c:0007 p:0029 s:0023 b:0023 l:000022 d:000022 METHOD /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:884<br>
c:0006 p:0022 s:0019 b:0019 l:000018 d:000018 METHOD /Users/sorah/git/ruby/ruby/lib/test/unit.rb:21<br>
c:0005 p:0016 s:0015 b:0015 l:000014 d:000014 METHOD /Users/sorah/git/ruby/ruby/lib/test/unit.rb:630<br>
c:0004 p:0019 s:0012 b:0012 l:000011 d:000011 METHOD /Users/sorah/git/ruby/ruby/lib/test/unit.rb:634<br>
c:0003 p:0156 s:0008 b:0007 l:001688 d:000830 EVAL ../../test/runner.rb:15<br>
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH<br>
c:0001 p:0000 s:0002 b:0002 l:001688 d:001688 TOP</p>
<p>-- Ruby level backtrace information ----------------------------------------<br>
../../test/runner.rb:15:in <code><main>' /Users/sorah/git/ruby/ruby/lib/test/unit.rb:634:in </code>run'<br>
/Users/sorah/git/ruby/ruby/lib/test/unit.rb:630:in <code>run' /Users/sorah/git/ruby/ruby/lib/test/unit.rb:21:in </code>run'<br>
/Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:884:in <code>run' /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:895:in </code>_run'<br>
/Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:895:in <code>each' /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:896:in </code>block in _run'<br>
/Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:909:in <code>run_tests' /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:746:in </code>_run_anything'<br>
/Users/sorah/git/ruby/ruby/lib/test/unit.rb:563:in <code>_run_suites' /Users/sorah/git/ruby/ruby/lib/test/unit.rb:563:in </code>each'<br>
/Users/sorah/git/ruby/ruby/lib/test/unit.rb:565:in <code>block in _run_suites' /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:780:in </code>_run_suite'<br>
/Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:780:in <code>map' /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:787:in </code>block in _run_suite'<br>
/Users/sorah/git/ruby/ruby/lib/test/unit/testcase.rb:17:in <code>run' /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb:948:in </code>run'<br>
/Users/sorah/git/ruby/ruby/test/ruby/test_enumerator.rb:328:in <code>test_feed_yielder' /Users/sorah/git/ruby/ruby/test/ruby/test_enumerator.rb:328:in </code>next'</p>
<p>-- C level backtrace information -------------------------------------------</p>
<p>See Crash Report log file under ~/Library/Logs/CrashReporter or<br>
/Library/Logs/CrashReporter, for the more detail of.</p>
<p>-- Other runtime information -----------------------------------------------</p>
<ul>
<li>
<p>Loaded script: ../../test/runner.rb</p>
</li>
<li>
<p>Loaded features:</p>
<p>0 enumerator.so<br>
1 /Users/sorah/git/ruby/ruby/builds/lion/.ext/x86_64-darwin11.0.0/enc/encdb.bundle<br>
2 /Users/sorah/git/ruby/ruby/builds/lion/.ext/x86_64-darwin11.0.0/enc/trans/transdb.bundle<br>
3 /Users/sorah/git/ruby/ruby/builds/lion/rbconfig.rb<br>
4 /Users/sorah/git/ruby/ruby/lib/optparse.rb<br>
5 /Users/sorah/git/ruby/ruby/lib/minitest/unit.rb<br>
6 /Users/sorah/git/ruby/ruby/lib/prettyprint.rb<br>
7 /Users/sorah/git/ruby/ruby/lib/pp.rb<br>
8 /Users/sorah/git/ruby/ruby/lib/test/unit/assertions.rb<br>
9 /Users/sorah/git/ruby/ruby/lib/test/unit/testcase.rb<br>
10 /Users/sorah/git/ruby/ruby/lib/test/unit.rb<br>
11 /Users/sorah/git/ruby/ruby/test/ruby/test_enumerator.rb</p>
</li>
</ul>
<p>[NOTE]<br>
You may have encountered a bug in the Ruby interpreter or extension libraries.<br>
Bug reports are welcome.<br>
For details: <a href="http://www.ruby-lang.org/bugreport.html" class="external">http://www.ruby-lang.org/bugreport.html</a></p>
<p>make: *** [yes-test-all] Abort trap: 6</p>
<hr>
<p>Process: ruby [39285]<br>
Path: /Users/USER/*/ruby<br>
Identifier: ruby<br>
Version: ??? (???)<br>
Code Type: X86-64 (Native)<br>
Parent Process: gnumake [37340]</p>
<p>Date/Time: 2011-07-22 14:52:10.251 +0900<br>
OS Version: Mac OS X 10.7 (11A511)<br>
Report Version: 9</p>
<p>Crashed Thread: 0 Dispatch queue: com.apple.main-thread</p>
<p>Exception Type: EXC_CRASH (SIGABRT)<br>
Exception Codes: 0x0000000000000000, 0x0000000000000000</p>
<p>Application Specific Information:<br>
objc[39285]: garbage collection is OFF<br>
abort() called</p>
<p>Thread 0 Crashed:: Dispatch queue: com.apple.main-thread<br>
0 libsystem_kernel.dylib 0x00007fff8e6abce2 __pthread_kill + 10<br>
1 libsystem_c.dylib 0x00007fff88bd07d2 pthread_kill + 95<br>
2 libsystem_c.dylib 0x00007fff88bc1a7a abort + 143<br>
3 libruby.1.9.1.dylib 0x0000000105feee39 rb_bug + 185<br>
4 libruby.1.9.1.dylib 0x00000001060f091f vm_call_method + 2511 (vm_insnhelper.c:407)<br>
5 libruby.1.9.1.dylib 0x00000001060f38ee vm_exec_core + 11726 (insns.def:1012)<br>
6 libruby.1.9.1.dylib 0x00000001060f7a6e vm_exec + 94 (vm.c:1181)<br>
7 libruby.1.9.1.dylib 0x00000001060f8986 rb_yield + 70 (vm_eval.c:747)<br>
8 libruby.1.9.1.dylib 0x0000000105fc285b rb_ary_collect + 123 (array.c:2220)<br>
9 libruby.1.9.1.dylib 0x00000001060ebd80 call_cfunc + 112 (vm_insnhelper.c:320)<br>
10 libruby.1.9.1.dylib 0x00000001060f0233 vm_call_method + 739 (vm_insnhelper.c:404)<br>
11 libruby.1.9.1.dylib 0x00000001060f38ee vm_exec_core + 11726 (insns.def:1012)<br>
12 libruby.1.9.1.dylib 0x00000001060f7a6e vm_exec + 94 (vm.c:1181)<br>
13 libruby.1.9.1.dylib 0x00000001060f8986 rb_yield + 70 (vm_eval.c:747)<br>
14 libruby.1.9.1.dylib 0x0000000105fc191f rb_ary_each + 95 (array.c:1477)<br>
15 libruby.1.9.1.dylib 0x00000001060ebd80 call_cfunc + 112 (vm_insnhelper.c:320)<br>
16 libruby.1.9.1.dylib 0x00000001060f0233 vm_call_method + 739 (vm_insnhelper.c:404)<br>
17 libruby.1.9.1.dylib 0x00000001060f38ee vm_exec_core + 11726 (insns.def:1012)<br>
18 libruby.1.9.1.dylib 0x00000001060f7a6e vm_exec + 94 (vm.c:1181)<br>
19 libruby.1.9.1.dylib 0x00000001060f8986 rb_yield + 70 (vm_eval.c:747)<br>
20 libruby.1.9.1.dylib 0x0000000105fc191f rb_ary_each + 95 (array.c:1477)<br>
21 libruby.1.9.1.dylib 0x00000001060ebd80 call_cfunc + 112 (vm_insnhelper.c:320)<br>
22 libruby.1.9.1.dylib 0x00000001060f0233 vm_call_method + 739 (vm_insnhelper.c:404)<br>
23 libruby.1.9.1.dylib 0x00000001060f38ee vm_exec_core + 11726 (insns.def:1012)<br>
24 libruby.1.9.1.dylib 0x00000001060f7a6e vm_exec + 94 (vm.c:1181)<br>
25 libruby.1.9.1.dylib 0x00000001060f81c3 rb_iseq_eval_main + 275 (vm.c:1422)<br>
26 libruby.1.9.1.dylib 0x0000000105ff16ef ruby_exec_internal + 111 (eval.c:209)<br>
27 libruby.1.9.1.dylib 0x0000000105ff26d2 ruby_run_node + 82 (eval.c:251)<br>
28 ruby 0x0000000105fb5ecf main + 79 (main.c:38)<br>
29 ruby 0x0000000105fb5e74 start + 52</p>
<p>Thread 1:<br>
0 libsystem_kernel.dylib 0x00007fff8e6abdf2 __select + 10<br>
1 libruby.1.9.1.dylib 0x00000001060fee21 thread_timer + 417 (thread_pthread.c:1137)<br>
2 libsystem_c.dylib 0x00007fff88bce8bf _pthread_start + 335<br>
3 libsystem_c.dylib 0x00007fff88bd1b75 thread_start + 13</p>
<p>Thread 0 crashed with X86 Thread State (64-bit):<br>
rax: 0x0000000000000000 rbx: 0x0000000000000006 rcx: 0x00007fff65bb2a48 rdx: 0x0000000000000000<br>
rdi: 0x0000000000002307 rsi: 0x0000000000000006 rbp: 0x00007fff65bb2a70 rsp: 0x00007fff65bb2a48<br>
r8: 0x00007fff7661bfb8 r9: 0x00007fff65bb25f8 r10: 0x00007fff8e6abd0a r11: 0xffffff80002d8240<br>
r12: 0x00000001064ff7c0 r13: 0x0000000106380ec0 r14: 0x00007fff7661e960 r15: 0x0000000000000008<br>
rip: 0x00007fff8e6abce2 rfl: 0x0000000000000246 cr2: 0x00007faf50a0e000<br>
Logical CPU: 0</p>
<p>Binary Images:<br>
0x105fb5000 - 0x105fb5ff7 +ruby (??? - ???) <9F6E5391-1596-3AD3-BE8D-7252D879373B> /Users/USER/<em>/ruby<br>
0x105fba000 - 0x10619afef +libruby.1.9.1.dylib (1.9.1 - compatibility 1.9.1) /Users/USER/</em>/libruby.1.9.1.dylib<br>
0x1062c1000 - 0x1062c2ff7 +encdb.bundle (??? - ???) /Users/USER/<em>/encdb.bundle<br>
0x1062c5000 - 0x1062c6fff +transdb.bundle (??? - ???) /Users/USER/</em>/transdb.bundle<br>
0x7fff65bb5000 - 0x7fff65be9ac7 dyld (195.5 - ???) <4A6E2B28-C7A2-3528-ADB7-4076B9836041> /usr/lib/dyld<br>
0x7fff8737a000 - 0x7fff87384ff7 liblaunch.dylib (392.18.0 - compatibility 1.0.0) <39EF04F2-7F0C-3435-B785-BF283727FFBD> /usr/lib/system/liblaunch.dylib<br>
0x7fff885a4000 - 0x7fff88619ff7 libc++.1.dylib (19.0.0 - compatibility 1.0.0) /usr/lib/libc++.1.dylib<br>
0x7fff886bf000 - 0x7fff886caff7 libc++abi.dylib (14.0.0 - compatibility 1.0.0) <8FF3D766-D678-36F6-84AC-423C878E6D14> /usr/lib/libc++abi.dylib<br>
0x7fff88921000 - 0x7fff88926fff libcache.dylib (47.0.0 - compatibility 1.0.0) /usr/lib/system/libcache.dylib<br>
0x7fff88a0b000 - 0x7fff88a13fff libsystem_dnssd.dylib (??? - ???) <7749128E-D0C5-3832-861C-BC9913F774FA> /usr/lib/system/libsystem_dnssd.dylib<br>
0x7fff88b80000 - 0x7fff88c5dfef libsystem_c.dylib (763.11.0 - compatibility 1.0.0) <1D61CA57-3C6D-30F7-89CB-CC6F0787B1DC> /usr/lib/system/libsystem_c.dylib<br>
0x7fff89a24000 - 0x7fff89a25fff libdnsinfo.dylib (395.6.0 - compatibility 1.0.0) <718A135F-6349-354A-85D5-430B128EFD57> /usr/lib/system/libdnsinfo.dylib<br>
0x7fff8a62c000 - 0x7fff8a62dfff libsystem_sandbox.dylib (??? - ???) <8D14139B-B671-35F4-9E5A-023B4C523C38> /usr/lib/system/libsystem_sandbox.dylib<br>
0x7fff8a62e000 - 0x7fff8a66afff libsystem_info.dylib (??? - ???) /usr/lib/system/libsystem_info.dylib<br>
0x7fff8a66b000 - 0x7fff8a679fff libdispatch.dylib (187.5.0 - compatibility 1.0.0) <698F8EFB-7075-3111-94E3-891156C88172> /usr/lib/system/libdispatch.dylib<br>
0x7fff8a856000 - 0x7fff8a858fff libquarantine.dylib (36.0.0 - compatibility 1.0.0) <4C3BFBC7-E592-3939-B376-1C2E2D7C5389> /usr/lib/system/libquarantine.dylib<br>
0x7fff8a8cf000 - 0x7fff8a8d5ff7 libunwind.dylib (30.0.0 - compatibility 1.0.0) <1E9C6C8C-CBE8-3F4B-A5B5-E03E3AB53231> /usr/lib/system/libunwind.dylib<br>
0x7fff8aa0c000 - 0x7fff8aa29ff7 libxpc.dylib (77.16.0 - compatibility 1.0.0) <0A4B4775-29A9-30D6-956B-3BE1DBF98090> /usr/lib/system/libxpc.dylib<br>
0x7fff8abaa000 - 0x7fff8ac8edef libobjc.A.dylib (228.0.0 - compatibility 1.0.0) /usr/lib/libobjc.A.dylib<br>
0x7fff8cf15000 - 0x7fff8cf63ff7 libauto.dylib (??? - ???) /usr/lib/libauto.dylib<br>
0x7fff8da1b000 - 0x7fff8da1bfff libkeymgr.dylib (23.0.0 - compatibility 1.0.0) <61EFED6A-A407-301E-B454-CD18314F0075> /usr/lib/system/libkeymgr.dylib<br>
0x7fff8e099000 - 0x7fff8e0dbff7 libcommonCrypto.dylib (55010.0.0 - compatibility 1.0.0) /usr/lib/system/libcommonCrypto.dylib<br>
0x7fff8e124000 - 0x7fff8e151fe7 libSystem.B.dylib (159.0.0 - compatibility 1.0.0) <7B4D685D-939C-3ABE-8780-77A1889E0DE9> /usr/lib/libSystem.B.dylib<br>
0x7fff8e596000 - 0x7fff8e597ff7 libremovefile.dylib (21.0.0 - compatibility 1.0.0) /usr/lib/system/libremovefile.dylib<br>
0x7fff8e695000 - 0x7fff8e6b5fff libsystem_kernel.dylib (1699.22.73 - compatibility 1.0.0) <69F2F501-72D8-3B3B-8357-F4418B3E1348> /usr/lib/system/libsystem_kernel.dylib<br>
0x7fff8e9fe000 - 0x7fff8ea02fff libmathCommon.A.dylib (2026.0.0 - compatibility 1.0.0) /usr/lib/system/libmathCommon.A.dylib<br>
0x7fff8fd3d000 - 0x7fff8fd3eff7 libsystem_blocks.dylib (53.0.0 - compatibility 1.0.0) <8BCA214A-8992-34B2-A8B9-B74DEACA1869> /usr/lib/system/libsystem_blocks.dylib<br>
0x7fff90063000 - 0x7fff9006afff libcopyfile.dylib (85.1.0 - compatibility 1.0.0) <172B1985-F24A-34E9-8D8B-A2403C9A0399> /usr/lib/system/libcopyfile.dylib<br>
0x7fff90645000 - 0x7fff9064aff7 libsystem_network.dylib (??? - ???) <4ABCEEF3-A3F9-3E06-9682-CE00F17138B7> /usr/lib/system/libsystem_network.dylib<br>
0x7fff9064b000 - 0x7fff9064ffff libdyld.dylib (195.5.0 - compatibility 1.0.0) /usr/lib/system/libdyld.dylib<br>
0x7fff90650000 - 0x7fff90651fff libunc.dylib (24.0.0 - compatibility 1.0.0) /usr/lib/system/libunc.dylib<br>
0x7fff90c0b000 - 0x7fff90c14fff libnotify.dylib (80.0.0 - compatibility 1.0.0) /usr/lib/system/libnotify.dylib<br>
0x7fff90c64000 - 0x7fff90c69fff libcompiler_rt.dylib (6.0.0 - compatibility 1.0.0) <98ECD5F6-E85C-32A5-98CD-8911230CB66A> /usr/lib/system/libcompiler_rt.dylib<br>
0x7fff913a3000 - 0x7fff913a9fff libmacho.dylib (800.0.0 - compatibility 1.0.0) /usr/lib/system/libmacho.dylib<br>
0x7fff913d8000 - 0x7fff9144bfff libstdc++.6.dylib (52.0.0 - compatibility 7.0.0) <6BDD43E4-A4B1-379E-9ED5-8C713653DFF2> /usr/lib/libstdc++.6.dylib</p>
<p>External Modification Summary:<br>
Calls made by other processes targeting this process:<br>
task_for_pid: 0<br>
thread_create: 0<br>
thread_set_state: 0<br>
Calls made by this process:<br>
task_for_pid: 0<br>
thread_create: 0<br>
thread_set_state: 0<br>
Calls made by all processes on this machine:<br>
task_for_pid: 246323<br>
thread_create: 0<br>
thread_set_state: 0</p>
<p>VM Region Summary:<br>
ReadOnly portion of Libraries: Total=54.2M resident=18.8M(35%) swapped_out_or_unallocated=35.5M(65%)<br>
Writable regions: Total=84.8M written=3496K(4%) resident=4620K(5%) swapped_out=0K(0%) unallocated=80.3M(95%)</p>
<p>REGION TYPE VIRTUAL<br>
=========== =======<br>
MALLOC 20.2M<br>
MALLOC guard page 16K<br>
MALLOC_LARGE (reserved) 256K reserved VM address space (unallocated)<br>
STACK GUARD 8K<br>
Stack 64.0M<br>
__DATA 688K<br>
__LINKEDIT 47.8M<br>
__TEXT 6644K<br>
shared memory 12K<br>
=========== =======<br>
TOTAL 139.4M<br>
TOTAL, minus reserved VM space 139.1M</p>
Ruby master - Bug #4992 (Closed): finalizer中のThread.newでSEGV
https://bugs.ruby-lang.org/issues/4992
2011-07-08T10:16:25Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>以下のようなコードを実行するとSEGVします.</p>
<p>$ ruby -e'ObjectSpace.define_finalizer(""){Thread.new{}}'<br>
$ ruby -e'ObjectSpace.define_finalizer(""){Thread.new{}}'<br>
SEGV received in SEGV handler<br>
$ ruby -e'ObjectSpace.define_finalizer(""){2.times{Thread.new{}}}'<br>
SEGV received in SEGV handler<br>
$ ruby -e'ObjectSpace.define_finalizer(""){2.times{Thread.new{}}}'<br>
SEGV received in SEGV handler</p>
<p>2.timesをつけるとほぼ確実,つけないと2回に1回くらいの割合で再現します.</p>
Ruby master - Bug #4686 (Closed): test/rubygems/test_gem_package_tar_output.rb should require rub...
https://bugs.ruby-lang.org/issues/4686
2011-05-13T17:02:03Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>Hi,</p>
<p>When run test-all with parallel option ("-j"), <code>test_self_open_signed(TestGemPackageTarOutput)</code> can be failed.</p>
<ol>
<li>Error:<br>
test_self_open_signed(TestGemPackageTarOutput):<br>
NameError: uninitialized constant Gem::Security<br>
/Users/sorah/git/ruby/ruby/test/rubygems/test_gem_package_tar_output.rb:61:in `test_self_open_signed'</li>
</ol>
<p>Because if running test-all with -j, the running order of test files can be not equal to the order when running test-all without -j.</p>
<p>So, if the test expects that already 'openssl' or 'rubygem/security' is required before that test runs,<br>
we should fix to require 'rubygem/security' on the top of the test file.</p>
<p>--<br>
Patch is below:</p>
<p>diff --git a/test/rubygems/test_gem_package_tar_output.rb b/test/rubygems/test_gem_package_tar_output.rb<br>
index 77f3185..01b4a0f 100644<br>
--- a/test/rubygems/test_gem_package_tar_output.rb<br>
+++ b/test/rubygems/test_gem_package_tar_output.rb<br>
@@ -6,6 +6,7 @@</p>
<p>require 'rubygems/package/tar_test_case'<br>
require 'rubygems/package/tar_output'<br>
+require 'rubygems/security'</p>
<p>class TestGemPackageTarOutput < Gem::Package::TarTestCase</p>
Ruby master - Feature #4657 (Closed): add option to hide skip messages on unit/test
https://bugs.ruby-lang.org/issues/4657
2011-05-09T18:31:26Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>最近test-allでSkipが多いので、skipのメッセージ表示を抑制するオプションを追加してはどうでしょう。</p>
<p>ちなみに、ruby-jaで以下のような流れがありました。</p>
<blockquote>
<p>nurse: そういえば、うささんの今のtest-allのskipって、test-allの最後で表示されたほうが嬉しいの?<br>
unak: まったくうれしくない。<br>
nurse: 今表示されてるのも消えたほうがいい?<br>
unak: skipの表示を抑制するオプションはほしい。</p>
</blockquote>
<p>以下のパッチを適用するとtest/unit (test-all)に--hide-skipオプションが追加され、<br>
--hide-skipオプションを付けて実行するとSkippedメッセージが表示されなくなります。</p>
<p>従来通り、Skip数は末尾のレポートで確認することができるようになっています。</p>
<p>出力例:</p>
<p>$ make TESTS='--hide-skip date' test-all<br>
./miniruby -I../../lib -I. -I.ext/common ../../tool/runruby.rb --extout=.ext -- "../../test/runner.rb" --ruby="./miniruby -I../../lib -I. -I.ext/common ../../tool/runruby.rb --extout=.ext --" --hide-skip date<br>
Run options: "--ruby=./miniruby -I../../lib -I. -I.ext/common ../../tool/runruby.rb --extout=.ext --" --hide-skip</p>
<a name="Running-tests"></a>
<h1 >Running tests:<a href="#Running-tests" class="wiki-anchor">¶</a></h1>
<p>..............................SSS....SSSSSSSSSSSSSSSS.SS........................................................................</p>
<p>Finished tests in 11.376260s, 11.2515 tests/s, 14151.3116 assertions/s.</p>
<p>128 tests, 160989 assertions, 0 failures, 0 errors, 21 skips</p>
<p>= patch below</p>
<p>diff --git lib/test/unit.rb lib/test/unit.rb<br>
index 1f1bb09..e88309f 100644<br>
--- lib/test/unit.rb<br>
+++ lib/test/unit.rb<br>
@@ -103,6 +103,10 @@ module Test<br>
opts.on '--ruby VAL', "Path to ruby; It'll have used at -j option" do |a|<br>
options[:ruby] = a.split(/ /).reject(&:empty?)<br>
end<br>
+</p>
<ul>
<li>
<pre><code> opts.on '--hide-skip', 'Hide skipped tests' do
</code></pre>
</li>
<li>
<pre><code> options[:hide_skip] = true
</code></pre>
</li>
<li>
<pre><code> end
end
def non_options(files, options)
</code></pre>
</li>
</ul>
<p>@@ -547,6 +551,7 @@ module Test<br>
end<br>
}<br>
end</p>
<ul>
<li>
<pre><code> report.reject!{|r| r.start_with? "Skipped:" } if @opts[:hide_skip]
result
end
</code></pre>
</li>
</ul>
<p>diff --git test/testunit/test4test_hideskip.rb test/testunit/test4test_hideskip.rb<br>
new file mode 100644<br>
index 0000000..6fe3284<br>
--- /dev/null<br>
+++ test/testunit/test4test_hideskip.rb<br>
@@ -0,0 +1,7 @@<br>
+require 'test/unit'<br>
+<br>
+class TestForTestHideSkip < Test::Unit::TestCase</p>
<ul>
<li>def test_skip</li>
<li>skip</li>
<li>end<br>
+end<br>
diff --git test/testunit/test_hideskip.rb test/testunit/test_hideskip.rb<br>
new file mode 100644<br>
index 0000000..967ecaf<br>
--- /dev/null<br>
+++ test/testunit/test_hideskip.rb<br>
@@ -0,0 +1,20 @@<br>
+require 'test/unit'</li>
<li>
</ul>
<p>+class TestHideSkip < Test::Unit::TestCase</p>
<ul>
<li>def test_hideskip</li>
<li>test_out, o = IO.pipe</li>
<li>spawn(*@options[:ruby], "#{File.dirname(<strong>FILE</strong>)}/test4test_hideskip.rb",</li>
<li>
<pre><code> out: o, err: o)
</code></pre>
</li>
<li>o.close</li>
<li>assert_match(/assertions/s.\n\n 1) Skipped/,test_out.read)</li>
<li>test_out.close</li>
<li>
<li>test_out, o = IO.pipe</li>
<li>spawn(*@options[:ruby], "#{File.dirname(<strong>FILE</strong>)}/test4test_hideskip.rb",</li>
<li>
<pre><code> "--hide-skip", out: o, err: o)
</code></pre>
</li>
<li>o.close</li>
<li>assert_match(/assertions/s.\n\n1 tests, 0 assertions, 0 failures, 0 errors, 1 skips/,</li>
<li>
<pre><code> test_out.read)
</code></pre>
</li>
<li>test_out.close</li>
<li>end<br>
+end</li>
</ul>
Ruby master - Bug #4433 (Closed): parallel_test中workerがrequireのwrong argument type StringIO (expe...
https://bugs.ruby-lang.org/issues/4433
2011-02-23T22:51:14Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>=begin<br>
trunkのmake TESTS='-j4 -v'で</p>
<p>TestRDocTopLevel#test_name = 0.08 s = .<br>
/Users/sorah/git/ruby/ruby/lib/rubygems/custom_require.rb:35:in <code>require': wrong argument type StringIO (expected File) (TypeError) from /Users/sorah/git/ruby/ruby/lib/rubygems/custom_require.rb:35:in </code>require'<br>
from /Users/sorah/git/ruby/ruby/test/readline/test_readline.rb:2:in <code><top (required)>' from /Users/sorah/git/ruby/ruby/lib/rubygems/custom_require.rb:35:in </code>require'<br>
from /Users/sorah/git/ruby/ruby/lib/rubygems/custom_require.rb:35:in <code>require' from /Users/sorah/git/ruby/ruby/lib/test/unit/parallel.rb:105:in </code>run'<br>
from /Users/sorah/git/ruby/ruby/lib/test/unit/parallel.rb:139:in `'<br>
Some worker was crashed. It seems ruby interpreter's bug<br>
or, a bug of test/unit/parallel.rb. try again without -j<br>
option.</p>
<p>make: *** [yes-test-all] Error 1</p>
<p>と例外を吐いて落ちることがあります。require 'readline' で何故こうなるのかよくわかりませんが。<br>
自分のr30939が原因なのかまだわかりませんが、近日中に調査して直します。</p>
<a name="-jを付けなければ影響はありません"></a>
<h1 >-jを付けなければ影響はありません。<a href="#-jを付けなければ影響はありません" class="wiki-anchor">¶</a></h1>
<p>=end</p>
Ruby master - Feature #4415 (Closed): Rubyのtest-allを並列化するパッチが完成しました
https://bugs.ruby-lang.org/issues/4415
2011-02-21T22:09:10Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>=begin</p>
<a name="ruby-dev43222-の続きです経緯などはそちらを参照していただければと思います"></a>
<h1 ><a href="https://blade.ruby-lang.org/ruby-dev/43222">[ruby-dev:43222]</a> の続きです。経緯などはそちらを参照していただければと思います。<a href="#ruby-dev43222-の続きです経緯などはそちらを参照していただければと思います" class="wiki-anchor">¶</a></h1>
<p>パッチが完成したのでチケットを作成しました。</p>
<p>まつもとさんは<a href="https://blade.ruby-lang.org/ruby-dev/43224">[ruby-dev:43224]</a>で「バグがとれたら入れちゃったら?」と言っていました。</p>
<p>一部テストについては改変していますが、それについては取りこまなくてもFailになることは無いと思います。<br>
(workerで失敗したテストは並列では無く実行をしなおす為。ただし若干速度に影響がでるかと)</p>
<p>では、コミットをよろしくお願いします。</p>
<p>--patch (git diff --no-prefix)--</p>
<p>diff --git lib/test/unit.rb lib/test/unit.rb<br>
index 76e9fdd..00d7e69 100644<br>
--- lib/test/unit.rb<br>
+++ lib/test/unit.rb<br>
@@ -51,6 +51,11 @@ module Test<br>
non_options(args, options)<br>
@help = orig_args.map { |s| s =~ /[\s|&<>$()]/ ? s.inspect : s }.join " "<br>
@options = options</p>
<ul>
<li>
<pre><code> @opts = @options = options
</code></pre>
</li>
<li>
<pre><code> if @options[:parallel]
</code></pre>
</li>
<li>
<pre><code> @files = args
</code></pre>
</li>
<li>
<pre><code> @args = orig_args
</code></pre>
</li>
<li>
<pre><code> end
end
private
</code></pre>
</li>
</ul>
<p>@@ -75,9 +80,35 @@ module Test<br>
opts.on '-n', '--name PATTERN', "Filter test names on pattern." do |a|<br>
options[:filter] = a<br>
end<br>
+</p>
<ul>
<li>
<pre><code> opts.on '--jobs-status [TYPE]', "Show status of jobs every file; Disabled when --jobs isn't specified." do |type|
</code></pre>
</li>
<li>
<pre><code> options[:job_status] = true
</code></pre>
</li>
<li>
<pre><code> options[:job_status_type] = type.to_sym if type
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> opts.on '-j N', '--jobs N', "Allow run tests with N jobs at once" do |a|
</code></pre>
</li>
<li>
<pre><code> options[:parallel] = a.to_i
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> opts.on '--no-retry', "Don't retry running testcase when --jobs specified" do
</code></pre>
</li>
<li>
<pre><code> options[:no_retry] = true
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> opts.on '--ruby VAL', "Path to ruby; It'll have used at -j option" do |a|
</code></pre>
</li>
<li>
<pre><code> options[:ruby] = a
</code></pre>
</li>
<li>
<pre><code> end
end
def non_options(files, options)
</code></pre>
</li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> require "rbconfig"
</code></pre>
</li>
<li>
<pre><code> rescue LoadError
</code></pre>
</li>
<li>
<pre><code> warn "#{caller(1)[0]}: warning: Parallel running disabled because can't get path to ruby; run specify with --ruby argument"
</code></pre>
</li>
<li>
<pre><code> options[:parallel] = nil
</code></pre>
</li>
<li>
<pre><code> else
</code></pre>
</li>
<li>
<pre><code> options[:ruby] = RbConfig.ruby
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> true
end
</code></pre>
end<br>
@@ -175,7 +206,7 @@ module Test<br>
$: << d<br>
end<br>
begin</li>
</ul>
<ul>
<li>
<pre><code> require path
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> require path unless options[:parallel]
result = true
rescue LoadError
puts "#{f}: #{$!}"
</code></pre>
</li>
</ul>
<p>@@ -186,32 +217,301 @@ module Test<br>
end</p>
<pre><code> class Runner < MiniTest::Unit
</code></pre>
<ul>
<li>
<pre><code> include Test::Unit::Options
</code></pre>
</li>
<li>
<pre><code> include Test::Unit::RequireFiles
include Test::Unit::GlobOption
include Test::Unit::LoadPathOption
include Test::Unit::GCStressOption
include Test::Unit::RunCount
class << self; undef autorun; end
</code></pre>
</li>
<li>
<li>
<pre><code> alias orig_run_anything _run_anything
</code></pre>
</li>
<li>
<pre><code> undef _run_anything
</code></pre>
</li>
<li>
<li>
<pre><code> def _run_anything type
</code></pre>
</li>
<li>
<pre><code> if @opts[:parallel] && @warnings
</code></pre>
</li>
<li>
<pre><code> warn ""
</code></pre>
</li>
<li>
<pre><code> ary = []
</code></pre>
</li>
<li>
<pre><code> @warnings.reject! do |w|
</code></pre>
</li>
<li>
<pre><code> r = ary.include?(w[1].message)
</code></pre>
</li>
<li>
<pre><code> ary << w[1].message
</code></pre>
</li>
<li>
<pre><code> r
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> @warnings.each do |w|
</code></pre>
</li>
<li>
<pre><code> warn "#{w[0]}: #{w[1].message} (#{w[1].class})"
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> warn ""
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> orig_run_anything(type)
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> @@stop_auto_run = false
def self.autorun
at_exit {
Test::Unit::RunCount.run_once {
exit(Test::Unit::Runner.new.run(ARGV) || true)
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> }
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> } unless @@stop_auto_run
} unless @@installed_at_exit
@@installed_at_exit = true
end
</code></pre>
</li>
<li>
<pre><code> def after_worker_down(worker, e=nil, c=1)
</code></pre>
</li>
<li>
<pre><code> return unless @opts[:parallel]
</code></pre>
</li>
<li>
<pre><code> return if @interrupt
</code></pre>
</li>
<li>
<pre><code> after_worker_dead worker
</code></pre>
</li>
<li>
<pre><code> if e
</code></pre>
</li>
<li>
<pre><code> b = e.backtrace
</code></pre>
</li>
<li>
<pre><code> warn "#{b.shift}: #{e.message} (#{e.class})"
</code></pre>
</li>
<li>
<pre><code> STDERR.print b.map{|s| "\tfrom #{s}"}.join("\n")
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> @need_quit = true
</code></pre>
</li>
<li>
<pre><code> warn ""
</code></pre>
</li>
<li>
<pre><code> warn "Some worker was crashed. It seems ruby interpreter's bug"
</code></pre>
</li>
<li>
<pre><code> warn "or, a bug of test/unit/parallel.rb. try again without -j"
</code></pre>
</li>
<li>
<pre><code> warn "option."
</code></pre>
</li>
<li>
<pre><code> warn ""
</code></pre>
</li>
<li>
<pre><code> STDERR.flush
</code></pre>
</li>
<li>
<pre><code> exit c
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> def jobs_status
</code></pre>
</li>
<li>
<pre><code> return unless @opts[:job_status]
</code></pre>
</li>
<li>
<pre><code> puts "" unless @opts[:verbose]
</code></pre>
</li>
<li>
<pre><code> if @opts[:job_status]
</code></pre>
</li>
<li>
<pre><code> b = []
</code></pre>
</li>
<li>
<pre><code> str = @workers.map { |x|
</code></pre>
</li>
<li>
<pre><code> a = "#{x[:pid]}:#{x[:status].to_s.ljust(7)}"
</code></pre>
</li>
<li>
<pre><code> if x[:file]
</code></pre>
</li>
<li>
<pre><code> if @opts[:job_status_type] == :replace
</code></pre>
</li>
<li>
<pre><code> a = "#{x[:pid]}=#{x[:file]}"
</code></pre>
</li>
<li>
<pre><code> else
</code></pre>
</li>
<li>
<pre><code> if a.size > x[:file].size
</code></pre>
</li>
<li>
<pre><code> b << x[:file].ljust(a.size)
</code></pre>
</li>
<li>
<pre><code> else
</code></pre>
</li>
<li>
<pre><code> a << " "*(x[:file].size-a.size)
</code></pre>
</li>
<li>
<pre><code> b << x[:file]
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> else
</code></pre>
</li>
<li>
<pre><code> b << " "*a.size
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> a
</code></pre>
</li>
<li>
<pre><code> }.join(" ")
</code></pre>
</li>
<li>
<pre><code> if @opts[:job_status_type] == :replace
</code></pre>
</li>
<li>
<pre><code> @terminal_width ||= %x{stty size 2>/dev/null}.split[1].to_i.nonzero? \
</code></pre>
</li>
<li>
<pre><code> || %x{tput cols 2>/dev/null}.to_i.nonzero? \
</code></pre>
</li>
<li>
<pre><code> || 80
</code></pre>
</li>
<li>
<pre><code> @jstr_size ||= 0
</code></pre>
</li>
<li>
<pre><code> del_jobs_status
</code></pre>
</li>
<li>
<pre><code> STDOUT.flush
</code></pre>
</li>
<li>
<pre><code> print str[0...@terminal_width]
</code></pre>
</li>
<li>
<pre><code> STDOUT.flush
</code></pre>
</li>
<li>
<pre><code> @jstr_size = str.size > @terminal_width ? @terminal_width : str.size
</code></pre>
</li>
<li>
<pre><code> else
</code></pre>
</li>
<li>
<pre><code> puts str
</code></pre>
</li>
<li>
<pre><code> puts b.join(" ")
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> def del_jobs_status
</code></pre>
</li>
<li>
<pre><code> return unless @opts[:job_status_type] == :replace && @jstr_size
</code></pre>
</li>
<li>
<pre><code> print "\r"+" "*@jstr_size+"\r"
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> def after_worker_dead(worker)
</code></pre>
</li>
<li>
<pre><code> return unless @opts[:parallel]
</code></pre>
</li>
<li>
<pre><code> return if @interrupt
</code></pre>
</li>
<li>
<pre><code> worker[:status] = :quit
</code></pre>
</li>
<li>
<pre><code> worker[:in].close
</code></pre>
</li>
<li>
<pre><code> worker[:out].close
</code></pre>
</li>
<li>
<pre><code> @workers.delete(worker)
</code></pre>
</li>
<li>
<pre><code> @dead_workers << worker
</code></pre>
</li>
<li>
<pre><code> @ios = @workers.map{|w| w[:out] }
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> def _run_suites suites, type
@interrupt = nil
result = []
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> suites.each {|suite|
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> if @opts[:parallel]
begin
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> result << _run_suite(suite, type)
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> # Require needed things for parallel running
</code></pre>
</li>
<li>
<pre><code> require 'thread'
</code></pre>
</li>
<li>
<pre><code> require 'timeout'
</code></pre>
</li>
<li>
<pre><code> @tasks = @files.dup # Array of filenames.
</code></pre>
</li>
<li>
<pre><code> @need_quit = false
</code></pre>
</li>
<li>
<pre><code> @dead_workers = [] # Array of dead workers.
</code></pre>
</li>
<li>
<pre><code> @warnings = []
</code></pre>
</li>
<li>
<pre><code> shutting_down = false
</code></pre>
</li>
<li>
<pre><code> errors = []
</code></pre>
</li>
<li>
<pre><code> failures = []
</code></pre>
</li>
<li>
<pre><code> skips = []
</code></pre>
</li>
<li>
<pre><code> rep = []
</code></pre>
</li>
<li>
<li>
<pre><code> # Array of workers.
</code></pre>
</li>
<li>
<pre><code> @workers = @opts[:parallel].times.map do
</code></pre>
</li>
<li>
<pre><code> i,o = IO.pipe("ASCII-8BIT") # worker o>|i> master
</code></pre>
</li>
<li>
<pre><code> j,k = IO.pipe("ASCII-8BIT") # worker <j|<k master
</code></pre>
</li>
<li>
<pre><code> k.sync = true
</code></pre>
</li>
<li>
<pre><code> pid = spawn(*@opts[:ruby].split(/ /),File.dirname(__FILE__) +
</code></pre>
</li>
<li>
<pre><code> "/unit/parallel.rb", *@args, out: o, in: j)
</code></pre>
</li>
<li>
<pre><code> [o,j].each{|io| io.close }
</code></pre>
</li>
<li>
<pre><code> {in: k, out: i, pid: pid, status: :waiting}
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> # Thread: watchdog
</code></pre>
</li>
<li>
<pre><code> watchdog = Thread.new do
</code></pre>
</li>
<li>
<pre><code> while stat = Process.wait2
</code></pre>
</li>
<li>
<pre><code> break if @interrupt # Break when interrupt
</code></pre>
</li>
<li>
<pre><code> w = (@workers + @dead_workers).find{|x| stat[0] == x[:pid] }.dup
</code></pre>
</li>
<li>
<pre><code> next unless w
</code></pre>
</li>
<li>
<pre><code> unless w[:status] == :quit
</code></pre>
</li>
<li>
<pre><code> # Worker down
</code></pre>
</li>
<li>
<pre><code> after_worker_down w, nil, stat[1].to_i
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> @workers_hash = Hash[@workers.map {|w| [w[:out],w] }] # out-IO => worker
</code></pre>
</li>
<li>
<pre><code> @ios = @workers.map{|w| w[:out] } # Array of worker IOs
</code></pre>
</li>
<li>
<li>
<pre><code> while _io = IO.select(@ios)[0]
</code></pre>
</li>
<li>
<pre><code> break unless _io.each do |io|
</code></pre>
</li>
<li>
<pre><code> break if @need_quit
</code></pre>
</li>
<li>
<pre><code> a = @workers_hash[io]
</code></pre>
</li>
<li>
<pre><code> buf = ((a[:status] == :quit) ? io.read : io.gets).chomp
</code></pre>
</li>
<li>
<pre><code> case buf
</code></pre>
</li>
<li>
<pre><code> when /^okay$/ # Worker will run task
</code></pre>
</li>
<li>
<pre><code> a[:status] = :running
</code></pre>
</li>
<li>
<pre><code> jobs_status
</code></pre>
</li>
<li>
<pre><code> when /^ready$/ # Worker is ready
</code></pre>
</li>
<li>
<pre><code> a[:status] = :ready
</code></pre>
</li>
<li>
<pre><code> if @tasks.empty?
</code></pre>
</li>
<li>
<pre><code> break unless @workers.find{|x| x[:status] == :running }
</code></pre>
</li>
<li>
<pre><code> else
</code></pre>
</li>
<li>
<pre><code> task = @tasks.shift
</code></pre>
</li>
<li>
<pre><code> a[:file] = File.basename(task).gsub(/\.rb/,"")
</code></pre>
</li>
<li>
<pre><code> a[:real_file] = task
</code></pre>
</li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> a[:loadpath] ||= []
</code></pre>
</li>
<li>
<pre><code> a[:in].puts "loadpath #{[Marshal.dump($:-a[:loadpath])].pack("m").gsub("\n","")}"
</code></pre>
</li>
<li>
<pre><code> a[:loadpath] = $:.dup
</code></pre>
</li>
<li>
<pre><code> a[:in].puts "run #{task} #{type}"
</code></pre>
</li>
<li>
<pre><code> a[:status] = :prepare
</code></pre>
</li>
<li>
<pre><code> rescue Errno::EPIPE
</code></pre>
</li>
<li>
<pre><code> after_worker_down a
</code></pre>
</li>
<li>
<pre><code> rescue IOError
</code></pre>
</li>
<li>
<pre><code> raise unless ["stream closed","closed stream"].include? $!.message
</code></pre>
</li>
<li>
<pre><code> after_worker_down a
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> jobs_status
</code></pre>
</li>
<li>
<pre><code> when /^done (.+?)$/ # Worker ran a one of suites in a file
</code></pre>
</li>
<li>
<pre><code> r = Marshal.load($1.unpack("m")[0])
</code></pre>
</li>
<li>
<pre><code> # [result,result,report,$:]
</code></pre>
</li>
<li>
<pre><code> result << r[0..1]
</code></pre>
</li>
<li>
<pre><code> rep << {file: a[:real_file], report: r[2], result: r[3],
</code></pre>
</li>
<li>
<pre><code> testcase: r[5]}
</code></pre>
</li>
<li>
<pre><code> errors << [a[:real_file],r[5],r[3][0]]
</code></pre>
</li>
<li>
<pre><code> failures << [a[:real_file],r[5],r[3][1]]
</code></pre>
</li>
<li>
<pre><code> skips << [a[:real_file],r[5],r[3][2]]
</code></pre>
</li>
<li>
<pre><code> $:.push(*r[4]).uniq!
</code></pre>
</li>
<li>
<pre><code> a[:status] = :done
</code></pre>
</li>
<li>
<pre><code> jobs_status if @opts[:job_status_type] == :replace
</code></pre>
</li>
<li>
<pre><code> a[:status] = :running
</code></pre>
</li>
<li>
<pre><code> when /^p (.+?)$/ # Worker wanna print to STDOUT
</code></pre>
</li>
<li>
<pre><code> del_jobs_status
</code></pre>
</li>
<li>
<pre><code> print $1.unpack("m")[0]
</code></pre>
</li>
<li>
<pre><code> jobs_status if @opts[:job_status_type] == :replace
</code></pre>
</li>
<li>
<pre><code> when /^after (.+?)$/
</code></pre>
</li>
<li>
<pre><code> @warnings << Marshal.load($1.unpack("m")[0])
</code></pre>
</li>
<li>
<pre><code> when /^bye (.+?)$/ # Worker will shutdown
</code></pre>
</li>
<li>
<pre><code> e = Marshal.load($1.unpack("m")[0])
</code></pre>
</li>
<li>
<pre><code> after_worker_down a, e
</code></pre>
</li>
<li>
<pre><code> when /^bye$/ # Worker will shutdown
</code></pre>
</li>
<li>
<pre><code> if shutting_down
</code></pre>
</li>
<li>
<pre><code> after_worker_dead a
</code></pre>
</li>
<li>
<pre><code> else
</code></pre>
</li>
<li>
<pre><code> after_worker_down a
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> break if @need_quit
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> # Retry
</code></pre>
</li>
<li>
<pre><code> # TODO: Interrupt?
rescue Interrupt => e
@interrupt = e
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> break
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> return result
</code></pre>
</li>
<li>
<pre><code> ensure
</code></pre>
</li>
<li>
<pre><code> shutting_down = true
</code></pre>
</li>
<li>
<li>
<pre><code> watchdog.kill if watchdog
</code></pre>
</li>
<li>
<pre><code> @workers.each do |w|
</code></pre>
</li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> timeout(1) do
</code></pre>
</li>
<li>
<pre><code> w[:in].puts "quit"
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> rescue Errno::EPIPE
</code></pre>
</li>
<li>
<pre><code> rescue Timeout::Error
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> [:in,:out].each do |x|
</code></pre>
</li>
<li>
<pre><code> w[x].close
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> timeout(0.2*@workers.size) do
</code></pre>
</li>
<li>
<pre><code> Process.waitall
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> rescue Timeout::Error
</code></pre>
</li>
<li>
<pre><code> @workers.each do |w|
</code></pre>
</li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> Process.kill(:KILL,w[:pid])
</code></pre>
</li>
<li>
<pre><code> rescue Errno::ESRCH; end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> unless @need_quit
</code></pre>
</li>
<li>
<pre><code> if @interrupt || @opts[:no_retry]
</code></pre>
</li>
<li>
<pre><code> rep.each do |r|
</code></pre>
</li>
<li>
<pre><code> report.push(*r[:report])
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> @errors += errors.map(&:last).inject(:+)
</code></pre>
</li>
<li>
<pre><code> @failures += failures.map(&:last).inject(:+)
</code></pre>
</li>
<li>
<pre><code> @skips += skips.map(&:last).inject(:+)
</code></pre>
</li>
<li>
<pre><code> else
</code></pre>
</li>
<li>
<pre><code> puts ""
</code></pre>
</li>
<li>
<pre><code> puts "Retrying..."
</code></pre>
</li>
<li>
<pre><code> puts ""
</code></pre>
</li>
<li>
<pre><code> @options = @opts
</code></pre>
</li>
<li>
<pre><code> rep.each do |r|
</code></pre>
</li>
<li>
<pre><code> if r[:testcase] && r[:file] && !r[:report].empty?
</code></pre>
</li>
<li>
<pre><code> require r[:file]
</code></pre>
</li>
<li>
<pre><code> _run_suite(eval(r[:testcase]),type)
</code></pre>
</li>
<li>
<pre><code> else
</code></pre>
</li>
<li>
<pre><code> report.push(*r[:report])
</code></pre>
</li>
<li>
<pre><code> @errors += r[:result][0]
</code></pre>
</li>
<li>
<pre><code> @failures += r[:result][1]
</code></pre>
</li>
<li>
<pre><code> @skips += r[:result][1]
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> end
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> }
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> else
</code></pre>
</li>
<li>
<pre><code> suites.each {|suite|
</code></pre>
</li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> result << _run_suite(suite, type)
</code></pre>
</li>
<li>
<pre><code> rescue Interrupt => e
</code></pre>
</li>
<li>
<pre><code> @interrupt = e
</code></pre>
</li>
<li>
<pre><code> break
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> end
result
end
</code></pre>
</li>
</ul>
<p>@@ -223,10 +523,6 @@ module Test<br>
end</p>
<pre><code> class AutoRunner
</code></pre>
<ul>
<li>
<pre><code> class Runner < Test::Unit::Runner
</code></pre>
</li>
<li>
<pre><code> include Test::Unit::RequireFiles
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> attr_accessor :to_run, :options
def initialize(force_standalone = false, default_dir = nil, argv = ARGV)
</code></pre>
</li>
</ul>
<p>diff --git lib/test/unit/parallel.rb lib/test/unit/parallel.rb<br>
new file mode 100644<br>
index 0000000..acfdc84<br>
--- /dev/null<br>
+++ lib/test/unit/parallel.rb<br>
@@ -0,0 +1,139 @@<br>
+require 'test/unit'<br>
+<br>
+module Test</p>
<ul>
<li>module Unit</li>
<li>class Worker < Runner</li>
<li>
<pre><code> class << self
</code></pre>
</li>
<li>
<pre><code> undef autorun
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> alias orig_run_suite _run_suite
</code></pre>
</li>
<li>
<pre><code> undef _run_suite
</code></pre>
</li>
<li>
<pre><code> undef _run_suites
</code></pre>
</li>
<li>
<li>
<pre><code> def _run_suites suites, type
</code></pre>
</li>
<li>
<pre><code> suites.map do |suite|
</code></pre>
</li>
<li>
<pre><code> result = _run_suite(suite, type)
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> def _run_suite(suite, type)
</code></pre>
</li>
<li>
<pre><code> r = report.dup
</code></pre>
</li>
<li>
<pre><code> orig_stdout = MiniTest::Unit.output
</code></pre>
</li>
<li>
<pre><code> i,o = IO.pipe
</code></pre>
</li>
<li>
<pre><code> MiniTest::Unit.output = o
</code></pre>
</li>
<li>
<li>
<pre><code> stdout = STDOUT.dup
</code></pre>
</li>
<li>
<li>
<pre><code> th = Thread.new(i.dup) do |io|
</code></pre>
</li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> while buf = (self.verbose ? io.gets : io.read(5))
</code></pre>
</li>
<li>
<pre><code> stdout.puts "p #{[buf].pack("m").gsub("\n","")}"
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> rescue IOError
</code></pre>
</li>
<li>
<pre><code> rescue Errno::EPIPE
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> e, f, s = @errors, @failures, @skips
</code></pre>
</li>
<li>
<li>
<pre><code> result = orig_run_suite(suite, type)
</code></pre>
</li>
<li>
<li>
<pre><code> MiniTest::Unit.output = orig_stdout
</code></pre>
</li>
<li>
<li>
<pre><code> o.close
</code></pre>
</li>
<li>
<pre><code> i.close
</code></pre>
</li>
<li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> th.join
</code></pre>
</li>
<li>
<pre><code> rescue IOError
</code></pre>
</li>
<li>
<pre><code> raise unless ["stream closed","closed stream"].include? $!.message
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> result << (report - r)
</code></pre>
</li>
<li>
<pre><code> result << [@errors-e,@failures-f,@skips-s]
</code></pre>
</li>
<li>
<pre><code> result << ($: - @old_loadpath)
</code></pre>
</li>
<li>
<pre><code> result << suite.name
</code></pre>
</li>
<li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> STDOUT.puts "done #{[Marshal.dump(result)].pack("m").gsub("\n","")}"
</code></pre>
</li>
<li>
<pre><code> rescue Errno::EPIPE; end
</code></pre>
</li>
<li>
<pre><code> return result
</code></pre>
</li>
<li>
<pre><code> ensure
</code></pre>
</li>
<li>
<pre><code> MiniTest::Unit.output = orig_stdout
</code></pre>
</li>
<li>
<pre><code> o.close if o && !o.closed?
</code></pre>
</li>
<li>
<pre><code> i.close if i && !i.closed?
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> def run(args = [])
</code></pre>
</li>
<li>
<pre><code> process_args args
</code></pre>
</li>
<li>
<pre><code> @@stop_auto_run = true
</code></pre>
</li>
<li>
<pre><code> @opts = @options.dup
</code></pre>
</li>
<li>
<li>
<pre><code> STDOUT.sync = true
</code></pre>
</li>
<li>
<pre><code> STDOUT.puts "ready"
</code></pre>
</li>
<li>
<pre><code> Signal.trap(:INT,"IGNORE")
</code></pre>
</li>
<li>
<li>
<li>
<pre><code> @old_loadpath = []
</code></pre>
</li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> stdin = STDIN.dup
</code></pre>
</li>
<li>
<pre><code> stdout = STDOUT.dup
</code></pre>
</li>
<li>
<pre><code> while buf = stdin.gets
</code></pre>
</li>
<li>
<pre><code> case buf.chomp
</code></pre>
</li>
<li>
<pre><code> when /^loadpath (.+?)$/
</code></pre>
</li>
<li>
<pre><code> @old_loadpath = $:.dup
</code></pre>
</li>
<li>
<pre><code> $:.push(*Marshal.load($1.unpack("m")[0].force_encoding("ASCII-8BIT"))).uniq!
</code></pre>
</li>
<li>
<pre><code> when /^run (.+?) (.+?)$/
</code></pre>
</li>
<li>
<pre><code> STDOUT.puts "okay"
</code></pre>
</li>
<li>
<li>
<pre><code> th = Thread.new do
</code></pre>
</li>
<li>
<pre><code> while puf = stdin.gets
</code></pre>
</li>
<li>
<pre><code> if puf.chomp == "quit"
</code></pre>
</li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> stdout.puts "bye"
</code></pre>
</li>
<li>
<pre><code> rescue Errno::EPIPE; end
</code></pre>
</li>
<li>
<pre><code> exit
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<li>
<pre><code> @options = @opts.dup
</code></pre>
</li>
<li>
<pre><code> suites = MiniTest::Unit::TestCase.test_suites
</code></pre>
</li>
<li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> require $1
</code></pre>
</li>
<li>
<pre><code> rescue LoadError
</code></pre>
</li>
<li>
<pre><code> th.kill
</code></pre>
</li>
<li>
<pre><code> STDOUT.puts "after #{[Marshal.dump([$1, $!])].pack("m").gsub("\n","")}"
</code></pre>
</li>
<li>
<pre><code> STDOUT.puts "ready"
</code></pre>
</li>
<li>
<pre><code> next
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> _run_suites MiniTest::Unit::TestCase.test_suites-suites, $2.to_sym
</code></pre>
</li>
<li>
<li>
<pre><code> STDIN.reopen(stdin)
</code></pre>
</li>
<li>
<pre><code> STDOUT.reopen(stdout)
</code></pre>
</li>
<li>
<li>
<pre><code> th.kill
</code></pre>
</li>
<li>
<pre><code> STDOUT.puts "ready"
</code></pre>
</li>
<li>
<pre><code> when /^quit$/
</code></pre>
</li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> STDOUT.puts "bye"
</code></pre>
</li>
<li>
<pre><code> rescue Errno::EPIPE; end
</code></pre>
</li>
<li>
<pre><code> exit
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> rescue Exception => e
</code></pre>
</li>
<li>
<pre><code> begin
</code></pre>
</li>
<li>
<pre><code> STDOUT.puts "bye #{[Marshal.dump(e)].pack("m").gsub("\n","")}"
</code></pre>
</li>
<li>
<pre><code> rescue Errno::EPIPE;end
</code></pre>
</li>
<li>
<pre><code> exit
</code></pre>
</li>
<li>
<pre><code> ensure
</code></pre>
</li>
<li>
<pre><code> stdin.close
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>end</li>
<li>end<br>
+end</li>
<li>
</ul>
<p>+Test::Unit::Worker.new.run(ARGV)<br>
diff --git test/csv/test_serialization.rb test/csv/test_serialization.rb<br>
index 0adb972..ba19b7a 100755<br>
--- test/csv/test_serialization.rb<br>
+++ test/csv/test_serialization.rb<br>
@@ -131,7 +131,7 @@ class TestCSV::Serialization < TestCSV<br>
def test_io<br>
test_class_dump</p>
<ul>
<li>data_file = File.join(File.dirname(<strong>FILE</strong>), "temp_test_data.csv")</li>
</ul>
<ul>
<li>
<p>data_file = File.join(File.dirname(<strong>FILE</strong>), "serialization_test_data.csv")<br>
CSV.dump(@names, File.open(data_file, "wb"))</p>
<p>assert(File.exist?(data_file))<br>
diff --git test/net/http/test_https.rb test/net/http/test_https.rb<br>
index 983ba7f..12684f6 100644<br>
--- test/net/http/test_https.rb<br>
+++ test/net/http/test_https.rb<br>
@@ -24,7 +24,7 @@ class TestNetHTTPS < Test::Unit::TestCase</p>
</li>
</ul>
<pre><code>CONFIG = {
'host' => '127.0.0.1',
</code></pre>
<ul>
<li>'port' => 10082, # different from test_http.rb</li>
</ul>
<ul>
<li>'port' => 10082,<br>
'proxy_host' => nil,<br>
'proxy_port' => nil,<br>
'ssl_enable' => true,<br>
diff --git test/rake/test_file_task.rb test/rake/test_file_task.rb<br>
index 1b0c0a5..0232ac9 100644<br>
--- test/rake/test_file_task.rb<br>
+++ test/rake/test_file_task.rb<br>
@@ -29,7 +29,9 @@ class Rake::TestFileTask < Test::Unit::TestCase<br>
end</li>
</ul>
<pre><code>def test_file_times_new_depends_on_old
</code></pre>
<ul>
<li>create_timed_files(OLDFILE, NEWFILE)</li>
</ul>
<ul>
<li>
<p>until File.exist?(OLDFILE) && File.exist?(NEWFILE)</p>
</li>
<li>
<pre><code> create_timed_files(OLDFILE, NEWFILE)
</code></pre>
</li>
<li>
<p>end</p>
<p>t1 = Rake.application.intern(FileTask, NEWFILE).enhance([OLDFILE])<br>
t2 = Rake.application.intern(FileTask, OLDFILE)<br>
@@ -38,7 +40,9 @@ class Rake::TestFileTask < Test::Unit::TestCase<br>
end</p>
</li>
</ul>
<pre><code>def test_file_times_old_depends_on_new
</code></pre>
<ul>
<li>create_timed_files(OLDFILE, NEWFILE)</li>
</ul>
<ul>
<li>
<p>until File.exist?(OLDFILE) && File.exist?(NEWFILE)</p>
</li>
<li>
<pre><code> create_timed_files(OLDFILE, NEWFILE)
</code></pre>
</li>
<li>
<p>end</p>
<p>t1 = Rake.application.intern(FileTask,OLDFILE).enhance([NEWFILE])<br>
t2 = Rake.application.intern(FileTask, NEWFILE)<br>
@@ -93,46 +97,46 @@ class Rake::TestDirectoryTask < Test::Unit::TestCase<br>
include Rake</p>
</li>
</ul>
<pre><code>def setup
</code></pre>
<ul>
<li>rm_rf "testdata", :verbose=>false</li>
</ul>
<ul>
<li>rm_rf "testdata2", :verbose=>false<br>
end</li>
</ul>
<pre><code>def teardown
</code></pre>
<ul>
<li>rm_rf "testdata", :verbose=>false</li>
</ul>
<ul>
<li>rm_rf "testdata2", :verbose=>false<br>
end</li>
</ul>
<pre><code>def test_directory
desc "DESC"
</code></pre>
<ul>
<li>directory "testdata/a/b/c"</li>
<li>assert_equal FileCreationTask, Task["testdata"].class</li>
<li>assert_equal FileCreationTask, Task["testdata/a"].class</li>
<li>assert_equal FileCreationTask, Task["testdata/a/b/c"].class</li>
<li>assert_nil Task["testdata"].comment</li>
<li>assert_equal "DESC", Task["testdata/a/b/c"].comment</li>
<li>assert_nil Task["testdata/a/b"].comment</li>
</ul>
<ul>
<li>directory "testdata2/a/b/c"</li>
<li>assert_equal FileCreationTask, Task["testdata2"].class</li>
<li>assert_equal FileCreationTask, Task["testdata2/a"].class</li>
<li>assert_equal FileCreationTask, Task["testdata2/a/b/c"].class</li>
<li>assert_nil Task["testdata2"].comment</li>
<li>assert_equal "DESC", Task["testdata2/a/b/c"].comment</li>
<li>assert_nil Task["testdata2/a/b"].comment<br>
verbose(false) {</li>
</ul>
<ul>
<li>
<pre><code> Task['testdata/a/b'].invoke
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> Task['testdata2/a/b'].invoke
</code></pre>
}</li>
</ul>
<ul>
<li>assert File.exist?("testdata/a/b")</li>
<li>assert ! File.exist?("testdata/a/b/c")</li>
</ul>
<ul>
<li>assert File.exist?("testdata2/a/b")</li>
<li>assert ! File.exist?("testdata2/a/b/c")<br>
end</li>
</ul>
<pre><code>if Rake::Win32.windows?
def test_directory_win32
desc "WIN32 DESC"
</code></pre>
<ul>
<li>
<pre><code> FileUtils.mkdir_p("testdata")
</code></pre>
</li>
<li>
<pre><code> Dir.chdir("testdata") do
</code></pre>
</li>
<li>
<pre><code> directory 'c:/testdata/a/b/c'
</code></pre>
</li>
<li>
<pre><code> assert_equal FileCreationTask, Task['c:/testdata'].class
</code></pre>
</li>
<li>
<pre><code> assert_equal FileCreationTask, Task['c:/testdata/a'].class
</code></pre>
</li>
<li>
<pre><code> assert_equal FileCreationTask, Task['c:/testdata/a/b/c'].class
</code></pre>
</li>
<li>
<pre><code> assert_nil Task['c:/testdata'].comment
</code></pre>
</li>
<li>
<pre><code> assert_equal "WIN32 DESC", Task['c:/testdata/a/b/c'].comment
</code></pre>
</li>
<li>
<pre><code> assert_nil Task['c:/testdata/a/b'].comment
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> FileUtils.mkdir_p("testdata2")
</code></pre>
</li>
<li>
<pre><code> Dir.chdir("testdata2") do
</code></pre>
</li>
<li>
<pre><code> directory 'c:/testdata2/a/b/c'
</code></pre>
</li>
<li>
<pre><code> assert_equal FileCreationTask, Task['c:/testdata2'].class
</code></pre>
</li>
<li>
<pre><code> assert_equal FileCreationTask, Task['c:/testdata2/a'].class
</code></pre>
</li>
<li>
<pre><code> assert_equal FileCreationTask, Task['c:/testdata2/a/b/c'].class
</code></pre>
</li>
<li>
<pre><code> assert_nil Task['c:/testdata2'].comment
</code></pre>
</li>
<li>
<pre><code> assert_equal "WIN32 DESC", Task['c:/testdata2/a/b/c'].comment
</code></pre>
</li>
<li>
<pre><code> assert_nil Task['c:/testdata2/a/b'].comment
verbose(false) {
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> Task['c:/testdata/a/b'].invoke
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> Task['c:/testdata2/a/b'].invoke
}
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> assert File.exist?('c:/testdata/a/b')
</code></pre>
</li>
<li>
<pre><code> assert ! File.exist?('c:/testdata/a/b/c')
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> assert File.exist?('c:/testdata2/a/b')
</code></pre>
</li>
<li>
<pre><code> assert ! File.exist?('c:/testdata2/a/b/c')
end
</code></pre>
end<br>
end<br>
=end</li>
</ul>
Ruby master - Bug #4407 (Closed): rubygems test should use require_relative
https://bugs.ruby-lang.org/issues/4407
2011-02-17T22:13:09Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>=begin<br>
hi,</p>
<p>rubygem's some tests should use require_relative.</p>
<p>Patch is here</p>
<p>diff --git test/rubygems/test_gem_format.rb test/rubygems/test_gem_format.rb<br>
index f964cab..b808398 100644<br>
--- test/rubygems/test_gem_format.rb<br>
+++ test/rubygems/test_gem_format.rb<br>
@@ -5,7 +5,11 @@<br>
######################################################################</p>
<p>require 'rubygems/package/tar_test_case'<br>
-require 'test/rubygems/simple_gem'<br>
+if respond_to?(:require_relative)</p>
<ul>
<li>require_relative 'simple_gem'<br>
+else</li>
<li>require "#{File.dirname(<strong>FILE</strong>)}/simple_gem"<br>
+end<br>
require 'rubygems/format'</li>
</ul>
<p>class TestGemFormat < Gem::Package::TarTestCase<br>
diff --git test/rubygems/test_gem_validator.rb test/rubygems/test_gem_validator.rb<br>
index aa4bd38..97491bf 100644<br>
--- test/rubygems/test_gem_validator.rb<br>
+++ test/rubygems/test_gem_validator.rb<br>
@@ -5,7 +5,11 @@<br>
######################################################################</p>
<p>require 'rubygems/test_case'<br>
-require "test/rubygems/simple_gem"<br>
+if respond_to?(:require_relative)</p>
<ul>
<li>require_relative 'simple_gem'<br>
+else</li>
<li>require "#{File.dirname(<strong>FILE</strong>)}/simple_gem"<br>
+end<br>
require 'rubygems/validator'</li>
</ul>
<p>class TestGemValidator < Gem::TestCase<br>
=end</p>
Ruby master - Bug #4275 (Closed): Directory CrashReport is not exist, CrashReporter is right.
https://bugs.ruby-lang.org/issues/4275
2011-01-13T09:59:34Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>=begin<br>
~/Library/Logs/CrashReportと/Library/Logs/CrashReportは存在しません。</p>
<p>ls: /Library/Logs/CrashReport: No such file or directory<br>
ls: /Users/sorah/Library/Logs/CrashReport: No such file or directory</p>
<p>その代わりにCrashReporterがあるのでそちらが正しいのではないでしょうか。</p>
<p>Patch:</p>
<p>diff --git vm_dump.c vm_dump.c<br>
index 741b4ad..3d6287c 100644<br>
--- vm_dump.c<br>
+++ vm_dump.c<br>
@@ -781,9 +781,9 @@ rb_vm_bugreport(void)</p>
<p>#if defined <strong>MACH</strong> && defined <strong>APPLE</strong><br>
fprintf(stderr, "-- See Crash Report log file under "</p>
<ul>
<li>
<pre><code> "~/Library/Logs/CrashReport or -----------\n");
</code></pre>
</li>
<li>fprintf(stderr, "-- /Library/Logs/CrashReport, for "</li>
<li>
<pre><code> "the more detail of -----------------------\n");
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> "~/Library/Logs/CrashReporter or ---------\n");
</code></pre>
</li>
<li>fprintf(stderr, "-- /Library/Logs/CrashReporter, for "</li>
<li>
<pre><code> "the more detail of ---------------------\n");
</code></pre>
</li>
</ul>
<p>#endif<br>
#if HAVE_BACKTRACE || defined(_WIN32)<br>
fprintf(stderr, "-- C level backtrace information "<br>
=end</p>
Ruby 1.8 - Feature #4239 (Closed): Let's begin a talk for "1.8.8" -- How's needed for surviving 1.8?
https://bugs.ruby-lang.org/issues/4239
2011-01-06T18:32:07Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>=begin<br>
###########################</p>
<a name="This-issue-is-translated-from-4207"></a>
<h1 >This issue is translated from <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: これから「1.8.8」の話をしよう -- 1.8がこの先生きのこるには (Closed)" href="https://bugs.ruby-lang.org/issues/4207">#4207</a>.<a href="#This-issue-is-translated-from-4207" class="wiki-anchor">¶</a></h1>
<a name="For-Japanese-This-translation-needs-proofreading-If-you-have-a-patch-please-send-to-sorahattubusudotnet"></a>
<h1 >For Japanese: This translation needs proofreading. If you have a patch, please send to sorah[at]tubusu[dot]net.<a href="#For-Japanese-This-translation-needs-proofreading-If-you-have-a-patch-please-send-to-sorahattubusudotnet" class="wiki-anchor">¶</a></h1>
<h1>Newer version of translation available at: <a href="https://gist.github.com/b2c4f223d3ee0bca72ad" class="external">https://gist.github.com/b2c4f223d3ee0bca72ad</a>
</h1>
<p>###########################</p>
<a name="httpredmineruby-langorgissuesshow4207"></a>
<h1 ><a href="http://redmine.ruby-lang.org/issues/show/4207" class="external">http://redmine.ruby-lang.org/issues/show/4207</a><a href="#httpredmineruby-langorgissuesshow4207" class="wiki-anchor">¶</a></h1>
<p>= Let's begin a talk for "1.8.8" -- How's needed for surviving 1.8?</p>
<p>Hi,</p>
<p>I know that we cannot release ruby_1_8 branch... more than anyone.</p>
<p>But the time past 3 years from 1.9.0, and 2.5 years from 1.8.7;<br>
it will be turned to 3 years in June 2011.</p>
<p>Why I'm marking "3 years," because releasing interval over 3 years<br>
first time ever, and almost systems have revised after 3 years from<br>
developed in my experience... so, almost codes which targets 1.8.7<br>
preparing to revised; I think.</p>
<p>Well, Which version used when codes which targets 1.8.7 are revised,<br>
I recommend 1.9.2 on my post, but almost can't use 1.9.x in<br>
actuality. Like, Extension libraries doesn't work.<br>
When can't use 1.9.x in codes, so it means use only 1.8.7. but it is<br>
really tough, for making tasks with 1.8.7, and I think that when I<br>
can give up maintaining 1.8.7? when my motivation is decreasing in<br>
future, it won't increase again. So I want to use new version,<br>
and don't use 1.8.7. New codes must target newer versions.</p>
<p>So, I want to set directions about 1.8.x future. I'm considing that<br>
destroy ruby_1_8 branch and we won't release 1.8.8 for a one of<br>
ideas. If we won't release 1.8.8, it means that can publish<br>
announcement about 1.8.7 is last version of 1.8 branch,then 1.8<br>
goes to last maintainance release. ah, in simplicity developers<br>
task is decreased; developers will be happy.</p>
<p>P.S.: I hope that people in a posision like Endoh Yusuke at 1.9.2.<br>
Anyone?</p>
<h3></h3>
<a name="httpredmineruby-langorgissuesshow4207note-6"></a>
<h1 ><a href="http://redmine.ruby-lang.org/issues/show/4207#note-6" class="external">http://redmine.ruby-lang.org/issues/show/4207#note-6</a><a href="#httpredmineruby-langorgissuesshow4207note-6" class="wiki-anchor">¶</a></h1>
<p>Well, Organize this issue without my factors, currently we have the following<br>
issues of 1.8.8.</p>
<ul>
<li>the time past 3 years from 1.9.0 released. In last 3 years, We released<br>
1.9.2 smoothly at 1.9 branch. Thanks Yugui (Yuki Sonoda).<br>
Also many users are using 1.9.x at forms of RailsDevCon.<br>
<a href="http://railsdevcon.jp/RailsDevCon2010report.pdf" class="external">http://railsdevcon.jp/RailsDevCon2010report.pdf</a>
</li>
<li>1.8.8 (and 1.8.7?) is on migration step to 1.9, but if we continue<br>
developing 1.8.8 at this rate and release 1.8.8 in 2020, do users which<br>
haven't migrated to 1.9 exist?</li>
<li>Currently does ruby_1_8 include any prompting structures to migrate<br>
1.9.x more than 1.8.7 at all? Just not merged same patches as 1.9?</li>
<li>"I want to release so I release. Any users didn't effect." is a one of<br>
views, but it makes unhappy by recognition differences?</li>
</ul>
<p>So.. Because 1.8 mustn't let be uncontrolled,<br>
I propose the following ideas which possible:</p>
<ol>
<li>Not today but ASAP, release 1.8.8 as "better 1.8.7." Release goal is this<br>
Summer.</li>
<li>Develop 1.8.8 until it's approached to ideal. Users can't be affect.<br>
Release goal is 2020 Christmas.</li>
<li>We won't release 1.8.8 never. Drop.</li>
<li>Otherwise I haven't thought yet.</li>
</ol>
<p>I don't specify any idea for adoption.<br>
Anyhow, I think that 1.8 mustn't keep current principle, so I asking "What do we do?"</p>
<p>Well.. what do we do?<br>
=end</p>
Ruby master - Bug #4092 (Closed): r29946 でビルドが通らない
https://bugs.ruby-lang.org/issues/4092
2010-11-27T13:04:00Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>=begin<br>
sora_hです。<br>
r29946でビルドが通りません。</p>
<p>diff --git lib/optparse.rb lib/optparse.rb<br>
index 91308a9..6d9c46f 100644<br>
--- lib/optparse.rb<br>
+++ lib/optparse.rb<br>
@@ -1549,7 +1549,7 @@ XXX<br>
end<br>
pat = Completion.regexp(word, true)<br>
visit(:each_option) do |opt|</p>
<ul>
<li>
<pre><code> opts = (long ? opt.long : []) + (short ? opt.short [])
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> opts = (long ? opt.long : []) + (short ? opt.short : [])
opts = Completion.candidate(word, true, pat, &opts.method(:each)).map(&:first) if pat
if /\A=/ =~ opt.arg
opts.map! {|sw| sw + "="}
</code></pre>
</li>
</ul>
<p>=end</p>
Ruby master - Bug #3985 (Closed): test_pathname fail on OSX via cron
https://bugs.ruby-lang.org/issues/3985
2010-10-26T20:23:44Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>=begin<br>
Shota Fukumori (sora_h)です</p>
<p>pathnameのtest_grpowned?がcron上でfailします。</p>
<ol>
<li>Failure:<br>
test_grpowned?(TestPathname) [/Users/sorah/git/ruby/ruby/test/pathname/test_pathname.rb:998]:<br>
expected but was<br>
.</li>
</ol>
<p>原因はOSXの/tmp以下のdirectoryがwheelになるからで、File.chownすることで解消しました。<br>
(なぜかコマンドラインからの実行だとfailしないけども)</p>
<p>パッチは以下です (git diff --no-prefixで生成):</p>
<p>diff --git test/pathname/test_pathname.rb test/pathname/test_pathname.rb<br>
index 235d0fb..86b85b8 100644<br>
--- test/pathname/test_pathname.rb<br>
+++ test/pathname/test_pathname.rb<br>
@@ -995,6 +995,7 @@ class TestPathname < Test::Unit::TestCase<br>
skip "Unix file owner test" if DOSISH<br>
with_tmpchdir('rubytest-pathname') {|dir|<br>
open("f", "w") {|f| f.write "abc" }</p>
<ul>
<li>
<pre><code> File.chown(-1, Process.gid, "f")
assert_equal(true, Pathname("f").grpowned?)
</code></pre>
}<br>
end<br>
=end</li>
</ul>
Ruby master - Bug #3858 (Closed): test_capture_io (test/minitest/test_mini_test.rb:837) doesn't pass
https://bugs.ruby-lang.org/issues/3858
2010-09-22T18:07:51Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>=begin<br>
Hi,</p>
<p>test_capture_io in test/minitest/test_mini_test.rb doesn't pass,<br>
because $VERBOSE is nil.</p>
<p>$VERBOSE == nil was fixed at recent commit (that is other test's bug),<br>
but $VERBOSE can't be decide always to !=nil because can't declare<br>
that same bug won't appear.</p>
<a name="The-patch-is-below"></a>
<h2 >The patch is below:<a href="#The-patch-is-below" class="wiki-anchor">¶</a></h2>
<p>diff --git test/minitest/test_mini_test.rb test/minitest/test_mini_test.rb<br>
index 1cbc829..bed0521 100644<br>
--- test/minitest/test_mini_test.rb<br>
+++ test/minitest/test_mini_test.rb<br>
@@ -828,6 +828,8 @@ FILE:LINE:in `test_assert_raises_triggered_subclass'<br>
def test_capture_io<br>
@assertion_count = 0</p>
<ul>
<li>
<p>orig_verbose = $VERBOSE</p>
</li>
<li>
<p>$VERBOSE = false<br>
out, err = capture_io do<br>
puts 'hi'<br>
warn 'bye!'<br>
@@ -835,6 +837,8 @@ FILE:LINE:in `test_assert_raises_triggered_subclass'</p>
<p>assert_equal "hi\n", out<br>
assert_equal "bye!\n", err</p>
</li>
<li>
<p>ensure</p>
</li>
<li>
<p>$VERBOSE = orig_verbose<br>
end</p>
</li>
</ul>
<pre><code>def test_class_asserts_match_refutes
</code></pre>
<hr>
<p>Thanks,<br>
Shota Fukumori (sora_h)<br>
=end</p>
Ruby master - Bug #3856 (Closed): test_capture_io (test/minitest/test_mini_test.rb:837)が通らない
https://bugs.ruby-lang.org/issues/3856
2010-09-22T16:48:57Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>=begin<br>
sora_hです。</p>
<p>test/minitest/test_minitest.rb:837 / test_capture_ioが通りません。</p>
<p>パッチは以下です。 #3852と同じ方法で修正がききます。</p>
<p>diff --git test/minitest/test_mini_test.rb test/minitest/test_mini_test.rb<br>
index 1cbc829..3a6b897 100644<br>
--- test/minitest/test_mini_test.rb<br>
+++ test/minitest/test_mini_test.rb<br>
@@ -828,10 +828,12 @@ FILE:LINE:in `test_assert_raises_triggered_subclass'<br>
def test_capture_io<br>
@assertion_count = 0</p>
<ul>
<li>
<p>orig_verbose, $VERBOSE = $VERBOSE, false<br>
out, err = capture_io do<br>
puts 'hi'<br>
warn 'bye!'<br>
end</p>
</li>
<li>
<p>$VERBOSE = orig_verbose</p>
<p>assert_equal "hi\n", out<br>
assert_equal "bye!\n", err<br>
=end</p>
</li>
</ul>
Ruby master - Bug #3852 (Closed): test_prime.rb:62が通らない
https://bugs.ruby-lang.org/issues/3852
2010-09-20T18:17:11Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>=begin<br>
test_prime.rb:62が以下のように通りませんでした。</p>
<ol>
<li>Error:<br>
test_new(TestPrime):<br>
IOError: not opened for reading<br>
../../test/test_prime.rb:62:in <code>read' ../../test/test_prime.rb:62:in </code>test_new'</li>
</ol>
<p>パッチは以下です。</p>
<p>diff --git test/test_prime.rb test/test_prime.rb<br>
index e095a29..dca9295 100644<br>
--- test/test_prime.rb<br>
+++ test/test_prime.rb<br>
@@ -55,7 +55,7 @@ class TestPrime < Test::Unit::TestCase<br>
end</p>
<pre><code>def test_new
</code></pre>
<ul>
<li>buf = StringIO.new('', 'w')</li>
</ul>
<ul>
<li>
<p>buf = StringIO.new('', 'w+')<br>
orig, $stderr = $stderr, buf</p>
<p>enum = Prime.new<br>
=end</p>
</li>
</ul>
Ruby master - Feature #3814 (Rejected): Prime.prime?をC拡張にする
https://bugs.ruby-lang.org/issues/3814
2010-09-10T15:47:26Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>=begin<br>
福森 (sora_h)です。</p>
<p>連続した自然数をInteger#timesで流していきそれが素数かを判定するスクリプトを書いたのですが、<br>
Rubyでprime.rbを使って書いたら200万で270秒ほどかかってテストに不便なので、<br>
ためしにPrime.prime?だけC拡張にしてみたら4秒になりました。</p>
<p>時間がかかるメソッドなどはc拡張にしてもいいかもしれません。</p>
<p><a href="http://github.com/sorah/euler/blob/master/problem10.rb" class="external">http://github.com/sorah/euler/blob/master/problem10.rb</a><br>
尚、270秒かかるスクリプトはこちらです</p>
<p>require 'prime'</p>
<p>p (1..2000000).to_a.reject { |x| p x if x % 10000 == 0; !x.prime? }.inject(:+)</p>
<p>以下にgit diff --no-prefixで生成したパッチを掲載します。</p>
<p>diff --git ext/prime/extconf.rb ext/prime/extconf.rb<br>
new file mode 100644<br>
index 0000000..c7e6941<br>
--- /dev/null<br>
+++ ext/prime/extconf.rb<br>
@@ -0,0 +1,3 @@<br>
+require 'mkmf'<br>
+<br>
+create_makefile('prime')<br>
diff --git ext/prime/lib/prime.rb ext/prime/lib/prime.rb<br>
new file mode 100644<br>
index 0000000..741164a<br>
--- /dev/null<br>
+++ ext/prime/lib/prime.rb<br>
@@ -0,0 +1,499 @@<br>
+#<br>
+# = prime.rb<br>
+#<br>
+# Prime numbers and factorization library.<br>
+#<br>
+# Copyright::<br>
+# Copyright (c) 1998-2008 Keiju ISHITSUKA(SHL Japan Inc.)<br>
+# Copyright (c) 2008 Yuki Sonoda (Yugui) <a href="mailto:yugui@yugui.jp" class="email">yugui@yugui.jp</a><br>
+#<br>
+# Documentation::<br>
+# Yuki Sonoda<br>
+#<br>
+<br>
+require "singleton"<br>
+require "forwardable"<br>
+<br>
+class Integer</p>
<ul>
<li>
<a name="Re-composes-a-prime-factorization-and-returns-the-product"></a>
<h1 >Re-composes a prime factorization and returns the product.<a href="#Re-composes-a-prime-factorization-and-returns-the-product" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="See-Primeint_from_prime_division-for-more-details"></a>
<h1 >See Prime#int_from_prime_division for more details.<a href="#See-Primeint_from_prime_division-for-more-details" class="wiki-anchor">¶</a></h1>
</li>
<li>def Integer.from_prime_division(pd)</li>
<li>Prime.int_from_prime_division(pd)</li>
<li>end</li>
<li>
<li>
<a name="Returns-the-factorization-of-self"></a>
<h1 >Returns the factorization of +self+.<a href="#Returns-the-factorization-of-self" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="See-Primeprime_division-for-more-details"></a>
<h1 >See Prime#prime_division for more details.<a href="#See-Primeprime_division-for-more-details" class="wiki-anchor">¶</a></h1>
</li>
<li>def prime_division(generator = Prime::Generator23.new)</li>
<li>Prime.prime_division(self, generator)</li>
<li>end</li>
<li>
<li>
<a name="Returns-true-if-self-is-a-prime-number-false-for-a-composite"></a>
<h1 >Returns true if +self+ is a prime number, false for a composite.<a href="#Returns-true-if-self-is-a-prime-number-false-for-a-composite" class="wiki-anchor">¶</a></h1>
</li>
<li>def prime?</li>
<li>Prime.prime?(self)</li>
<li>end</li>
<li>
<li>
<a name="Iterates-the-given-block-over-all-prime-numbers"></a>
<h1 >Iterates the given block over all prime numbers.<a href="#Iterates-the-given-block-over-all-prime-numbers" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="See-Primeeach-for-more-details"></a>
<h1 >See +Prime+#each for more details.<a href="#See-Primeeach-for-more-details" class="wiki-anchor">¶</a></h1>
</li>
<li>def Integer.each_prime(ubound, &block) # :yields: prime</li>
<li>Prime.each(ubound, &block)</li>
<li>end<br>
+end</li>
<li>
</ul>
<p>+#<br>
+# The set of all prime numbers.<br>
+#<br>
+# == Example<br>
+# Prime.each(100) do |prime|<br>
+# p prime #=> 2, 3, 5, 7, 11, ...., 97<br>
+# end<br>
+#<br>
+# == Retrieving the instance<br>
+# +Prime+.new is obsolete. Now +Prime+ has the default instance and you can<br>
+# access it as +Prime+.instance.<br>
+#<br>
+# For convenience, each instance method of +Prime+.instance can be accessed<br>
+# as a class method of +Prime+.<br>
+#<br>
+# e.g.<br>
+# Prime.instance.prime?(2) #=> true<br>
+# Prime.prime?(2) #=> true<br>
+#<br>
+# == Generators<br>
+# A "generator" provides an implementation of enumerating pseudo-prime<br>
+# numbers and it remembers the position of enumeration and upper bound.<br>
+# Futhermore, it is a external iterator of prime enumeration which is<br>
+# compatible to an Enumerator.<br>
+#<br>
+# +Prime+::+PseudoPrimeGenerator+ is the base class for generators.<br>
+# There are few implementations of generator.<br>
+#<br>
+# [+Prime+::+EratosthenesGenerator+]<br>
+# Uses eratosthenes's sieve.<br>
+# [+Prime+::+TrialDivisionGenerator+]<br>
+# Uses the trial division method.<br>
+# [+Prime+::+Generator23+]<br>
+# Generates all positive integers which is not divided by 2 nor 3.<br>
+# This sequence is very bad as a pseudo-prime sequence. But this<br>
+# is faster and uses much less memory than other generators. So,<br>
+# it is suitable for factorizing an integer which is not large but<br>
+# has many prime factors. e.g. for Prime#prime? .<br>
+class Prime</p>
<ul>
<li>include Enumerable</li>
<li>@the_instance = Prime.new</li>
<li>
<li>
<a name="obsolete-Use-Primeinstance-or-class-methods-of-Prime"></a>
<h1 >obsolete. Use +Prime+::+instance+ or class methods of +Prime+.<a href="#obsolete-Use-Primeinstance-or-class-methods-of-Prime" class="wiki-anchor">¶</a></h1>
</li>
<li>def initialize</li>
<li>@generator = EratosthenesGenerator.new</li>
<li>extend OldCompatibility</li>
<li>warn "Prime::new is obsolete. use Prime::instance or class methods of Prime."</li>
<li>end</li>
<li>
<li>class << self</li>
<li>extend Forwardable</li>
<li>include Enumerable</li>
<li>
<a name="Returns-the-default-instance-of-Prime"></a>
<h1 >Returns the default instance of Prime.<a href="#Returns-the-default-instance-of-Prime" class="wiki-anchor">¶</a></h1>
</li>
<li>def instance; @the_instance end</li>
<li>
<li>def method_added(method) # :nodoc:</li>
<li>
<pre><code> (class<< self;self;end).def_delegator :instance, method
</code></pre>
</li>
<li>end</li>
<li>end</li>
<li>
<li>
<a name="Iterates-the-given-block-over-all-prime-numbers-2"></a>
<h1 >Iterates the given block over all prime numbers.<a href="#Iterates-the-given-block-over-all-prime-numbers-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Parameters"></a>
<h1 >== Parameters<a href="#-Parameters" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="ubound"></a>
<h1 >+ubound+::<a href="#ubound" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="Optional-An-arbitrary-positive-number"></a>
<h1 >Optional. An arbitrary positive number.<a href="#Optional-An-arbitrary-positive-number" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="The-upper-bound-of-enumeration-The-method-enumerates"></a>
<h1 >The upper bound of enumeration. The method enumerates<a href="#The-upper-bound-of-enumeration-The-method-enumerates" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="prime-numbers-infinitely-if-ubound-is-nil"></a>
<h1 >prime numbers infinitely if +ubound+ is nil.<a href="#prime-numbers-infinitely-if-ubound-is-nil" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="generator"></a>
<h1 >+generator+::<a href="#generator" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="Optional-An-implementation-of-pseudo-prime-generator"></a>
<h1 >Optional. An implementation of pseudo-prime generator.<a href="#Optional-An-implementation-of-pseudo-prime-generator" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Return-value"></a>
<h1 >== Return value<a href="#-Return-value" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="An-evaluated-value-of-the-given-block-at-the-last-time"></a>
<h1 >An evaluated value of the given block at the last time.<a href="#An-evaluated-value-of-the-given-block-at-the-last-time" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="Or-an-enumerator-which-is-compatible-to-an-Enumerator"></a>
<h1 >Or an enumerator which is compatible to an +Enumerator+<a href="#Or-an-enumerator-which-is-compatible-to-an-Enumerator" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="if-no-block-given"></a>
<h1 >if no block given.<a href="#if-no-block-given" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Description"></a>
<h1 >== Description<a href="#-Description" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="Calls-block-once-for-each-prime-number-passing-the-prime-as"></a>
<h1 >Calls +block+ once for each prime number, passing the prime as<a href="#Calls-block-once-for-each-prime-number-passing-the-prime-as" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="a-parameter"></a>
<h1 >a parameter.<a href="#a-parameter" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="ubound-2"></a>
<h1 >+ubound+::<a href="#ubound-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="Upper-bound-of-prime-numbers-The-iterator-stops-after"></a>
<h1 >Upper bound of prime numbers. The iterator stops after<a href="#Upper-bound-of-prime-numbers-The-iterator-stops-after" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="yields-all-prime-numbers-p-lt-ubound"></a>
<h1 >yields all prime numbers p <= +ubound+.<a href="#yields-all-prime-numbers-p-lt-ubound" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Note"></a>
<h1 >== Note<a href="#-Note" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="Primenew-returns-a-object-extended-by-PrimeOldCompatibility"></a>
<h1 >+Prime+.+new+ returns a object extended by +Prime+::+OldCompatibility+<a href="#Primenew-returns-a-object-extended-by-PrimeOldCompatibility" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="in-order-to-compatibility-to-Ruby-18-and-Primeeach-is-overwritten"></a>
<h1 >in order to compatibility to Ruby 1.8, and +Prime+#each is overwritten<a href="#in-order-to-compatibility-to-Ruby-18-and-Primeeach-is-overwritten" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="by-PrimeOldCompatibilityeach"></a>
<h1 >by +Prime+::+OldCompatibility+#+each+.<a href="#by-PrimeOldCompatibilityeach" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="Primenew-is-now-obsolete-Use-Primeinstanceeach-or-simply"></a>
<h1 >+Prime+.+new+ is now obsolete. Use +Prime+.+instance+.+each+ or simply<a href="#Primenew-is-now-obsolete-Use-Primeinstanceeach-or-simply" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="Primeeach"></a>
<h1 >+Prime+.+each+.<a href="#Primeeach" class="wiki-anchor">¶</a></h1>
</li>
<li>def each(ubound = nil, generator = EratosthenesGenerator.new, &block)</li>
<li>generator.upper_bound = ubound</li>
<li>generator.each(&block)</li>
<li>end</li>
<li>
<li>
<li>
<a name="Returns-true-if-value-is-prime-false-for-a-composite"></a>
<h1 >Returns true if +value+ is prime, false for a composite.<a href="#Returns-true-if-value-is-prime-false-for-a-composite" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Parameters-2"></a>
<h1 >== Parameters<a href="#-Parameters-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="value-an-arbitrary-integer-to-be-checked"></a>
<h1 >+value+:: an arbitrary integer to be checked.<a href="#value-an-arbitrary-integer-to-be-checked" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="generator-optional-A-pseudo-prime-generator"></a>
<h1 >+generator+:: optional. A pseudo-prime generator.<a href="#generator-optional-A-pseudo-prime-generator" class="wiki-anchor">¶</a></h1>
</li>
<li>def prime?(value, generator = Prime::Generator23.new)</li>
<li>value = -value if value < 0</li>
<li>return false if value < 2</li>
<li>for num in generator</li>
<li>
<pre><code> q,r = value.divmod num
</code></pre>
</li>
<li>
<pre><code> return true if q < num
</code></pre>
</li>
<li>
<pre><code> return false if r == 0
</code></pre>
</li>
<li>end</li>
<li>end</li>
<li>
<li>
<a name="Re-composes-a-prime-factorization-and-returns-the-product-2"></a>
<h1 >Re-composes a prime factorization and returns the product.<a href="#Re-composes-a-prime-factorization-and-returns-the-product-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Parameters-3"></a>
<h1 >== Parameters<a href="#-Parameters-3" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="pd-Array-of-pairs-of-integers-The-each-internal"></a>
<h1 >+pd+:: Array of pairs of integers. The each internal<a href="#pd-Array-of-pairs-of-integers-The-each-internal" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="pair-consists-of-a-prime-number-a-prime-factor-"></a>
<h1 >pair consists of a prime number -- a prime factor --<a href="#pair-consists-of-a-prime-number-a-prime-factor-" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="and-a-natural-number-an-exponent"></a>
<h1 >and a natural number -- an exponent.<a href="#and-a-natural-number-an-exponent" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Example"></a>
<h1 >== Example<a href="#-Example" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="For-p_1-e_1-p_2-e_2-p_n-e_n-it-returns"></a>
<h1 >For [[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]], it returns<a href="#For-p_1-e_1-p_2-e_2-p_n-e_n-it-returns" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="p_1e_1-p_2e_2-p_ne_n"></a>
<h1 >p_1<strong>e_1 * p_2</strong>e_2 * .... * p_n**e_n.<a href="#p_1e_1-p_2e_2-p_ne_n" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="Primeint_from_prime_division22-31-gt-12"></a>
<h1 >Prime.int_from_prime_division([[2,2], [3,1]]) #=> 12<a href="#Primeint_from_prime_division22-31-gt-12" class="wiki-anchor">¶</a></h1>
</li>
<li>def int_from_prime_division(pd)</li>
<li>pd.inject(1){|value, (prime, index)|</li>
<li>
<pre><code> value *= prime**index
</code></pre>
</li>
<li>}</li>
<li>end</li>
<li>
<li>
<a name="Returns-the-factorization-of-value"></a>
<h1 >Returns the factorization of +value+.<a href="#Returns-the-factorization-of-value" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Parameters-4"></a>
<h1 >== Parameters<a href="#-Parameters-4" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="value-An-arbitrary-integer"></a>
<h1 >+value+:: An arbitrary integer.<a href="#value-An-arbitrary-integer" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="generator-Optional-A-pseudo-prime-generator"></a>
<h1 >+generator+:: Optional. A pseudo-prime generator.<a href="#generator-Optional-A-pseudo-prime-generator" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="generatorsucc-must-return-the-next"></a>
<h1 >+generator+.succ must return the next<a href="#generatorsucc-must-return-the-next" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="pseudo-prime-number-in-the-ascendent"></a>
<h1 >pseudo-prime number in the ascendent<a href="#pseudo-prime-number-in-the-ascendent" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="order-It-must-generate-all-prime-numbers"></a>
<h1 >order. It must generate all prime numbers,<a href="#order-It-must-generate-all-prime-numbers" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="but-may-generate-non-prime-numbers"></a>
<h1 >but may generate non prime numbers.<a href="#but-may-generate-non-prime-numbers" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Exceptions"></a>
<h1 >=== Exceptions<a href="#-Exceptions" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="ZeroDivisionError-when-value-is-zero"></a>
<h1 >+ZeroDivisionError+:: when +value+ is zero.<a href="#ZeroDivisionError-when-value-is-zero" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Example-2"></a>
<h1 >== Example<a href="#-Example-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="For-an-arbitrary-integer"></a>
<h1 >For an arbitrary integer<a href="#For-an-arbitrary-integer" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="n-p_1e_1-p_2e_2-p_ne_n"></a>
<h1 >n = p_1<strong>e_1 * p_2</strong>e_2 * .... * p_n**e_n,<a href="#n-p_1e_1-p_2e_2-p_ne_n" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="prime_divisionn-returns"></a>
<h1 >prime_division(n) returns<a href="#prime_divisionn-returns" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="p_1-e_1-p_2-e_2-p_n-e_n"></a>
<h1 >[[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]].<a href="#p_1-e_1-p_2-e_2-p_n-e_n" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="Primeprime_division12-gt-22-31"></a>
<h1 >Prime.prime_division(12) #=> [[2,2], [3,1]]<a href="#Primeprime_division12-gt-22-31" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>def prime_division(value, generator= Prime::Generator23.new)</li>
<li>raise ZeroDivisionError if value == 0</li>
<li>if value < 0</li>
<li>
<pre><code> value = -value
</code></pre>
</li>
<li>
<pre><code> pv = [[-1, 1]]
</code></pre>
</li>
<li>else</li>
<li>
<pre><code> pv = []
</code></pre>
</li>
<li>end</li>
<li>for prime in generator</li>
<li>
<pre><code> count = 0
</code></pre>
</li>
<li>
<pre><code> while (value1, mod = value.divmod(prime)
</code></pre>
</li>
<li>
<pre><code> mod) == 0
</code></pre>
</li>
<li>value = value1</li>
<li>count += 1</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> if count != 0
</code></pre>
</li>
<li>pv.push [prime, count]</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> break if value1 <= prime
</code></pre>
</li>
<li>end</li>
<li>if value > 1</li>
<li>
<pre><code> pv.push [value, 1]
</code></pre>
</li>
<li>end</li>
<li>return pv</li>
<li>end</li>
<li>
<li>
<a name="An-abstract-class-for-enumerating-pseudo-prime-numbers"></a>
<h1 >An abstract class for enumerating pseudo-prime numbers.<a href="#An-abstract-class-for-enumerating-pseudo-prime-numbers" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="Concrete-subclasses-should-override-succ-next-rewind"></a>
<h1 >Concrete subclasses should override succ, next, rewind.<a href="#Concrete-subclasses-should-override-succ-next-rewind" class="wiki-anchor">¶</a></h1>
</li>
<li>class PseudoPrimeGenerator</li>
<li>include Enumerable</li>
<li>
<li>def initialize(ubound = nil)</li>
<li>
<pre><code> @ubound = ubound
</code></pre>
</li>
<li>end</li>
<li>
<li>def upper_bound=(ubound)</li>
<li>
<pre><code> @ubound = ubound
</code></pre>
</li>
<li>end</li>
<li>def upper_bound</li>
<li>
<pre><code> @ubound
</code></pre>
</li>
<li>end</li>
<li>
<li>
<a name="returns-the-next-pseudo-prime-number-and-move-the-internal"></a>
<h1 >returns the next pseudo-prime number, and move the internal<a href="#returns-the-next-pseudo-prime-number-and-move-the-internal" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="position-forward"></a>
<h1 >position forward.<a href="#position-forward" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="PseudoPrimeGeneratorsucc-raises-NotImplementedError"></a>
<h1 >+PseudoPrimeGenerator+#succ raises +NotImplementedError+.<a href="#PseudoPrimeGeneratorsucc-raises-NotImplementedError" class="wiki-anchor">¶</a></h1>
</li>
<li>def succ</li>
<li>
<pre><code> raise NotImplementedError, "need to define `succ'"
</code></pre>
</li>
<li>end</li>
<li>
<li>
<a name="alias-of-succ"></a>
<h1 >alias of +succ+.<a href="#alias-of-succ" class="wiki-anchor">¶</a></h1>
</li>
<li>def next</li>
<li>
<pre><code> raise NotImplementedError, "need to define `next'"
</code></pre>
</li>
<li>end</li>
<li>
<li>
<a name="Rewinds-the-internal-position-for-enumeration"></a>
<h1 >Rewinds the internal position for enumeration.<a href="#Rewinds-the-internal-position-for-enumeration" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="See-Enumeratorrewind"></a>
<h1 >See +Enumerator+#rewind.<a href="#See-Enumeratorrewind" class="wiki-anchor">¶</a></h1>
</li>
<li>def rewind</li>
<li>
<pre><code> raise NotImplementedError, "need to define `rewind'"
</code></pre>
</li>
<li>end</li>
<li>
<li>
<a name="Iterates-the-given-block-for-each-prime-numbers"></a>
<h1 >Iterates the given block for each prime numbers.<a href="#Iterates-the-given-block-for-each-prime-numbers" class="wiki-anchor">¶</a></h1>
</li>
<li>def each(&block)</li>
<li>
<pre><code> return self.dup unless block
</code></pre>
</li>
<li>
<pre><code> if @ubound
</code></pre>
</li>
<li>last_value = nil</li>
<li>loop do</li>
<li>prime = succ</li>
<li>break last_value if prime > @ubound</li>
<li>last_value = block.call(prime)</li>
<li>end</li>
<li>
<pre><code> else
</code></pre>
</li>
<li>loop do</li>
<li>block.call(succ)</li>
<li>end</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>end</li>
<li>
<li>
<a name="see-Enumeratorwith_index"></a>
<h1 >see +Enumerator+#with_index.<a href="#see-Enumeratorwith_index" class="wiki-anchor">¶</a></h1>
</li>
<li>alias with_index each_with_index</li>
<li>
<li>
<a name="see-Enumeratorwith_object"></a>
<h1 >see +Enumerator+#with_object.<a href="#see-Enumeratorwith_object" class="wiki-anchor">¶</a></h1>
</li>
<li>def with_object(obj)</li>
<li>
<pre><code> return enum_for(:with_object) unless block_given?
</code></pre>
</li>
<li>
<pre><code> each do |prime|
</code></pre>
</li>
<li>yield prime, obj</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>end</li>
<li>end</li>
<li>
<li>
<a name="An-implementation-of-PseudoPrimeGenerator"></a>
<h1 >An implementation of +PseudoPrimeGenerator+.<a href="#An-implementation-of-PseudoPrimeGenerator" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="Uses-EratosthenesSieve"></a>
<h1 >Uses +EratosthenesSieve+.<a href="#Uses-EratosthenesSieve" class="wiki-anchor">¶</a></h1>
</li>
<li>class EratosthenesGenerator < PseudoPrimeGenerator</li>
<li>def initialize</li>
<li>
<pre><code> @last_prime = nil
</code></pre>
</li>
<li>
<pre><code> super
</code></pre>
</li>
<li>end</li>
<li>
<li>def succ</li>
<li>
<pre><code> @last_prime = @last_prime ? EratosthenesSieve.instance.next_to(@last_prime) : 2
</code></pre>
</li>
<li>end</li>
<li>def rewind</li>
<li>
<pre><code> initialize
</code></pre>
</li>
<li>end</li>
<li>alias next succ</li>
<li>end</li>
<li>
<li>
<a name="An-implementation-of-PseudoPrimeGenerator-which-uses"></a>
<h1 >An implementation of +PseudoPrimeGenerator+ which uses<a href="#An-implementation-of-PseudoPrimeGenerator-which-uses" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="a-prime-table-generated-by-trial-division"></a>
<h1 >a prime table generated by trial division.<a href="#a-prime-table-generated-by-trial-division" class="wiki-anchor">¶</a></h1>
</li>
<li>class TrialDivisionGenerator<PseudoPrimeGenerator</li>
<li>def initialize</li>
<li>
<pre><code> @index = -1
</code></pre>
</li>
<li>
<pre><code> super
</code></pre>
</li>
<li>end</li>
<li>
<li>def succ</li>
<li>
<pre><code> TrialDivision.instance[@index += 1]
</code></pre>
</li>
<li>end</li>
<li>def rewind</li>
<li>
<pre><code> initialize
</code></pre>
</li>
<li>end</li>
<li>alias next succ</li>
<li>end</li>
<li>
<li>
<a name="Generates-all-integer-which-are-greater-than-2-and"></a>
<h1 >Generates all integer which are greater than 2 and<a href="#Generates-all-integer-which-are-greater-than-2-and" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="are-not-divided-by-2-nor-3"></a>
<h1 >are not divided by 2 nor 3.<a href="#are-not-divided-by-2-nor-3" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="This-is-a-pseudo-prime-generator-suitable-on"></a>
<h1 >This is a pseudo-prime generator, suitable on<a href="#This-is-a-pseudo-prime-generator-suitable-on" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="checking-primality-of-a-integer-by-brute-force"></a>
<h1 >checking primality of a integer by brute force<a href="#checking-primality-of-a-integer-by-brute-force" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="method"></a>
<h1 >method.<a href="#method" class="wiki-anchor">¶</a></h1>
</li>
<li>class Generator23<PseudoPrimeGenerator</li>
<li>def initialize</li>
<li>
<pre><code> @prime = 1
</code></pre>
</li>
<li>
<pre><code> @step = nil
</code></pre>
</li>
<li>
<pre><code> super
</code></pre>
</li>
<li>end</li>
<li>
<li>def succ</li>
<li>
<pre><code> loop do
</code></pre>
</li>
<li>if (@step)</li>
<li>@prime += @step</li>
<li>@step = 6 - @step</li>
<li>else</li>
<li>case @prime</li>
<li>when 1; @prime = 2</li>
<li>when 2; @prime = 3</li>
<li>when 3; @prime = 5; @step = 2</li>
<li>end</li>
<li>end</li>
<li>return @prime</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>end</li>
<li>alias next succ</li>
<li>def rewind</li>
<li>
<pre><code> initialize
</code></pre>
</li>
<li>end</li>
<li>end</li>
<li>
<li>
<li>
<li>
<li>
<a name="Internal-use-An-implementation-of-prime-table-by-trial-division-method"></a>
<h1 >Internal use. An implementation of prime table by trial division method.<a href="#Internal-use-An-implementation-of-prime-table-by-trial-division-method" class="wiki-anchor">¶</a></h1>
</li>
<li>class TrialDivision</li>
<li>include Singleton</li>
<li>
<li>def initialize # :nodoc:</li>
<li>
<pre><code> # These are included as class variables to cache them for later uses. If memory
</code></pre>
</li>
<li>
<pre><code> # usage is a problem, they can be put in Prime#initialize as instance variables.
</code></pre>
</li>
<li>
<li>
<pre><code> # There must be no primes between @primes[-1] and @next_to_check.
</code></pre>
</li>
<li>
<pre><code> @primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101]
</code></pre>
</li>
<li>
<pre><code> # @next_to_check % 6 must be 1.
</code></pre>
</li>
<li>
<pre><code> @next_to_check = 103 # @primes[-1] - @primes[-1] % 6 + 7
</code></pre>
</li>
<li>
<pre><code> @ulticheck_index = 3 # @primes.index(@primes.reverse.find {|n|
</code></pre>
</li>
<li>
<pre><code> # n < Math.sqrt(@@next_to_check) })
</code></pre>
</li>
<li>
<pre><code> @ulticheck_next_squared = 121 # @primes[@ulticheck_index + 1] ** 2
</code></pre>
</li>
<li>end</li>
<li>
<li>
<a name="Returns-the-cached-prime-numbers"></a>
<h1 >Returns the cached prime numbers.<a href="#Returns-the-cached-prime-numbers" class="wiki-anchor">¶</a></h1>
</li>
<li>def cache</li>
<li>
<pre><code> return @primes
</code></pre>
</li>
<li>end</li>
<li>alias primes cache</li>
<li>alias primes_so_far cache</li>
<li>
<li>
<a name="Returns-the-indexth-prime-number"></a>
<h1 >Returns the +index+th prime number.<a href="#Returns-the-indexth-prime-number" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="index-is-a-0-based-index"></a>
<h1 >+index+ is a 0-based index.<a href="#index-is-a-0-based-index" class="wiki-anchor">¶</a></h1>
</li>
<li>def <a href="index"></a>
</li>
<li>
<pre><code> while index >= @primes.length
</code></pre>
</li>
<li>
<a name="Only-check-for-prime-factors-up-to-the-square-root-of-the-potential-primes"></a>
<h1 >Only check for prime factors up to the square root of the potential primes,<a href="#Only-check-for-prime-factors-up-to-the-square-root-of-the-potential-primes" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="but-without-the-performance-hit-of-an-actual-square-root-calculation"></a>
<h1 >but without the performance hit of an actual square root calculation.<a href="#but-without-the-performance-hit-of-an-actual-square-root-calculation" class="wiki-anchor">¶</a></h1>
</li>
<li>if @next_to_check + 4 > @ulticheck_next_squared</li>
<li>@ulticheck_index += 1</li>
<li>@ulticheck_next_squared = @primes.at(@ulticheck_index + 1) ** 2</li>
<li>end</li>
<li>
<a name="Only-check-numbers-congruent-to-one-and-five-modulo-six-All-others"></a>
<h1 >Only check numbers congruent to one and five, modulo six. All others<a href="#Only-check-numbers-congruent-to-one-and-five-modulo-six-All-others" class="wiki-anchor">¶</a></h1>
</li>
<li>
<li>
<a name="are-divisible-by-two-or-three-This-also-allows-us-to-skip-checking-against"></a>
<h1 >are divisible by two or three. This also allows us to skip checking against<a href="#are-divisible-by-two-or-three-This-also-allows-us-to-skip-checking-against" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="two-and-three"></a>
<h1 >two and three.<a href="#two-and-three" class="wiki-anchor">¶</a></h1>
</li>
<li>@primes.push @next_to_check if @primes[2..@ulticheck_index].find {|prime| @next_to_check % prime == 0 }.nil?</li>
<li>@next_to_check += 4</li>
<li>@primes.push @next_to_check if @primes[2..@ulticheck_index].find {|prime| @next_to_check % prime == 0 }.nil?</li>
<li>@next_to_check += 2</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> return @primes[index]
</code></pre>
</li>
<li>end</li>
<li>end</li>
<li>
<li>
<a name="Internal-use-An-implementation-of-eratostheness-sieve"></a>
<h1 >Internal use. An implementation of eratosthenes's sieve<a href="#Internal-use-An-implementation-of-eratostheness-sieve" class="wiki-anchor">¶</a></h1>
</li>
<li>class EratosthenesSieve</li>
<li>include Singleton</li>
<li>
<li>BITS_PER_ENTRY = 16 # each entry is a set of 16-bits in a Fixnum</li>
<li>NUMS_PER_ENTRY = BITS_PER_ENTRY * 2 # twiced because even numbers are omitted</li>
<li>ENTRIES_PER_TABLE = 8</li>
<li>NUMS_PER_TABLE = NUMS_PER_ENTRY * ENTRIES_PER_TABLE</li>
<li>FILLED_ENTRY = (1 << NUMS_PER_ENTRY) - 1</li>
<li>
<li>def initialize # :nodoc:</li>
<li>
<pre><code> # bitmap for odd prime numbers less than 256.
</code></pre>
</li>
<li>
<pre><code> # For an arbitrary odd number n, @tables[i][j][k] is
</code></pre>
</li>
<li>
<pre><code> # * 1 if n is prime,
</code></pre>
</li>
<li>
<pre><code> # * 0 if n is composite,
</code></pre>
</li>
<li>
<pre><code> # where i,j,k = indices(n)
</code></pre>
</li>
<li>
<pre><code> @tables = [[0xcb6e, 0x64b4, 0x129a, 0x816d, 0x4c32, 0x864a, 0x820d, 0x2196].freeze]
</code></pre>
</li>
<li>end</li>
<li>
<li>
<a name="returns-the-least-odd-prime-number-which-is-greater-than-n"></a>
<h1 >returns the least odd prime number which is greater than +n+.<a href="#returns-the-least-odd-prime-number-which-is-greater-than-n" class="wiki-anchor">¶</a></h1>
</li>
<li>def next_to(n)</li>
<li>
<pre><code> n = (n-1).div(2)*2+3 # the next odd number to given n
</code></pre>
</li>
<li>
<pre><code> table_index, integer_index, bit_index = indices(n)
</code></pre>
</li>
<li>
<pre><code> loop do
</code></pre>
</li>
<li>extend_table until @tables.length > table_index</li>
<li>for j in integer_index...ENTRIES_PER_TABLE</li>
<li>if !@tables[table_index][j].zero?</li>
<li>
<pre><code> for k in bit_index...BITS_PER_ENTRY
</code></pre>
</li>
<li>
<pre><code> return NUMS_PER_TABLE*table_index + NUMS_PER_ENTRY*j + 2*k+1 if !@tables[table_index][j][k].zero?
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>end</li>
<li>bit_index = 0</li>
<li>end</li>
<li>table_index += 1; integer_index = 0</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>end</li>
<li>
<li>private</li>
<li>
<a name="for-an-odd-number-n-returns-i-j-k-such-that-tablesijk-represents-primarity-of-the-number"></a>
<h1 >for an odd number +n+, returns (i, j, k) such that @tables[i][j][k] represents primarity of the number<a href="#for-an-odd-number-n-returns-i-j-k-such-that-tablesijk-represents-primarity-of-the-number" class="wiki-anchor">¶</a></h1>
</li>
<li>def indices(n)</li>
<li>
<pre><code> # binary digits of n: |0|1|2|3|4|5|6|7|8|9|10|11|....
</code></pre>
</li>
<li>
<pre><code> # indices: |-| k | j | i
</code></pre>
</li>
<li>
<pre><code> # because of NUMS_PER_ENTRY, NUMS_PER_TABLE
</code></pre>
</li>
<li>
<li>
<pre><code> k = (n & 0b00011111) >> 1
</code></pre>
</li>
<li>
<pre><code> j = (n & 0b11100000) >> 5
</code></pre>
</li>
<li>
<pre><code> i = n >> 8
</code></pre>
</li>
<li>
<pre><code> return i, j, k
</code></pre>
</li>
<li>end</li>
<li>
<li>def extend_table</li>
<li>
<pre><code> lbound = NUMS_PER_TABLE * @tables.length
</code></pre>
</li>
<li>
<pre><code> ubound = lbound + NUMS_PER_TABLE
</code></pre>
</li>
<li>
<pre><code> new_table = [FILLED_ENTRY] * ENTRIES_PER_TABLE # which represents primarity in lbound...ubound
</code></pre>
</li>
<li>
<pre><code> (3..Integer(Math.sqrt(ubound))).step(2) do |p|
</code></pre>
</li>
<li>i, j, k = indices(p)</li>
<li>next if @tables[i][j][k].zero?</li>
<li>
<li>start = (lbound.div(p)+1)*p # least multiple of p which is >= lbound</li>
<li>start += p if start.even?</li>
<li>(start...ubound).step(2*p) do |n|</li>
<li>_, j, k = indices(n)</li>
<li>new_table[j] &= FILLED_ENTRY^(1<<k)</li>
<li>end</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> @tables << new_table.freeze
</code></pre>
</li>
<li>end</li>
<li>end</li>
<li>
<li>
<a name="Provides-a-Prime-object-with-compatibility-to-Ruby-18-when-instantiated-via-Primenew"></a>
<h1 >Provides a +Prime+ object with compatibility to Ruby 1.8 when instantiated via +Prime+.+new+.<a href="#Provides-a-Prime-object-with-compatibility-to-Ruby-18-when-instantiated-via-Primenew" class="wiki-anchor">¶</a></h1>
</li>
<li>module OldCompatibility</li>
<li>
<a name="Returns-the-next-prime-number-and-forwards-internal-pointer"></a>
<h1 >Returns the next prime number and forwards internal pointer.<a href="#Returns-the-next-prime-number-and-forwards-internal-pointer" class="wiki-anchor">¶</a></h1>
</li>
<li>def succ</li>
<li>
<pre><code> @generator.succ
</code></pre>
</li>
<li>end</li>
<li>alias next succ</li>
<li>
<li>
<a name="Overwrites-Primeeach"></a>
<h1 >Overwrites Prime#each.<a href="#Overwrites-Primeeach" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="Iterates-the-given-block-over-all-prime-numbers-Note-that-enumeration-starts-from"></a>
<h1 >Iterates the given block over all prime numbers. Note that enumeration starts from<a href="#Iterates-the-given-block-over-all-prime-numbers-Note-that-enumeration-starts-from" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="the-current-position-of-internal-pointer-not-rewound"></a>
<h1 >the current position of internal pointer, not rewound.<a href="#the-current-position-of-internal-pointer-not-rewound" class="wiki-anchor">¶</a></h1>
</li>
<li>def each(&block)</li>
<li>
<pre><code> return @generator.dup unless block_given?
</code></pre>
</li>
<li>
<pre><code> loop do
</code></pre>
</li>
<li>yield succ</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>end</li>
<li>end<br>
+end</li>
<li>
<li>
</ul>
<p>+require 'prime.so'<br>
+<br>
diff --git ext/prime/prime.c ext/prime/prime.c<br>
new file mode 100644<br>
index 0000000..9f182a3<br>
--- /dev/null<br>
+++ ext/prime/prime.c<br>
@@ -0,0 +1,96 @@<br>
+/************************************************<br>
+</p>
<ul>
<li>prime.c -</li>
<li>
<li>Copyright (C) 2010 Shota Fukumori (sora_h)</li>
<li>
</ul>
<p>+************************************************/<br>
+<br>
+#include "ruby/ruby.h"<br>
+<br>
+VALUE prime_um_value;<br>
+<br>
+static VALUE<br>
+prime_is_value_prime(int argc, VALUE *argv, VALUE self) {</p>
<ul>
<li>int step23, v, g;</li>
<li>long int i, x;</li>
<li>VALUE value, generator, t, iv;</li>
<li>
<li>rb_scan_args(argc, argv, "11", &value, &generator);</li>
<li>
<li>if(TYPE(value) == T_FLOAT)</li>
<li>return Qfalse;</li>
<li>
<li>if(!(FIXNUM_P(value) || TYPE(value) == T_BIGNUM))</li>
<li>rb_raise(rb_eTypeError, "value must be a numeric");</li>
<li>if(!prime_um_value)</li>
<li>prime_um_value = ULONG2NUM(ULONG_MAX);</li>
<li>
<li>if (!FIXNUM_P(value) && rb_funcall(value,rb_intern(">"),1,prime_um_value) == Qtrue){</li>
<li>v = 1;</li>
<li>if (rb_funcall(value,rb_intern("<"),1,INT2FIX(2)) == Qtrue)</li>
<li>
<pre><code> return Qfalse;
</code></pre>
</li>
<li>if (rb_funcall(value,rb_intern("=="),1,INT2FIX(2)) == Qtrue ||</li>
<li>
<pre><code> rb_funcall(value,rb_intern("=="),1,INT2FIX(3)) == Qtrue)
</code></pre>
</li>
<li>
<pre><code> return Qtrue;
</code></pre>
</li>
<li>} else {</li>
<li>v = 0;</li>
<li>x = NUM2LONG(value);</li>
<li>if (x < 0) x = x * -1;</li>
<li>
<li>if (x < 2) return Qfalse;</li>
<li>if (x == 2) return Qtrue;</li>
<li>if (x == 3) return Qtrue;</li>
<li>}</li>
<li>step23 = 0;</li>
<li>i = 1;</li>
<li>while(1) {</li>
<li>if(g = NIL_P(generator)) {</li>
<li>
<pre><code> if (step23 < 1) {
</code></pre>
</li>
<li>
<pre><code> switch(i) {
</code></pre>
</li>
<li>
<pre><code> case 1:
</code></pre>
</li>
<li>
<pre><code> i = 2;
</code></pre>
</li>
<li>
<pre><code> break;
</code></pre>
</li>
<li>
<pre><code> case 2:
</code></pre>
</li>
<li>
<pre><code> i = 3;
</code></pre>
</li>
<li>
<pre><code> break;
</code></pre>
</li>
<li>
<pre><code> case 3:
</code></pre>
</li>
<li>
<pre><code> i = 5;
</code></pre>
</li>
<li>
<pre><code> step23 = 2;
</code></pre>
</li>
<li>
<pre><code> break;
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> }else{
</code></pre>
</li>
<li>
<pre><code> i += step23;
</code></pre>
</li>
<li>
<pre><code> step23 = 6 - step23;
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>}else{</li>
<li>
<pre><code> iv = rb_funcall(generator,rb_intern("succ"),0);
</code></pre>
</li>
<li>
<pre><code> if (!v) i = NUM2ULONG(iv);
</code></pre>
</li>
<li>}</li>
<li>if (v) {</li>
<li>
<pre><code> if (!g) iv = ULONG2NUM(i);
</code></pre>
</li>
<li>
<pre><code> t = rb_funcall(value,rb_intern("divmod"),1,iv);
</code></pre>
</li>
<li>
<pre><code> if (rb_funcall(rb_ary_shift(t),rb_intern("<"),1,iv) == Qtrue)
</code></pre>
</li>
<li>
<pre><code> return Qtrue;
</code></pre>
</li>
<li>
<pre><code> if (rb_funcall(rb_ary_shift(t),rb_intern("=="),1,INT2FIX(0)) == Qtrue)
</code></pre>
</li>
<li>
<pre><code> return Qfalse;
</code></pre>
</li>
<li>} else {</li>
<li>
<pre><code> if (x / i < i)
</code></pre>
</li>
<li>
<pre><code> return Qtrue;
</code></pre>
</li>
<li>
<pre><code> if (x % i == 0)
</code></pre>
</li>
<li>
<pre><code> return Qfalse;
</code></pre>
</li>
<li>}</li>
<li>}</li>
<li>/*}else{</li>
<li>i = rb</li>
<li>return Qfalse; NOTE: fix this</li>
<li>}*/<br>
+}</li>
<li>
</ul>
<p>+void<br>
+Init_prime(void) {</p>
<ul>
<li>VALUE rb_cPrime;</li>
<li>rb_cPrime = rb_define_class("Prime", rb_cObject);</li>
<li>
<li>rb_define_singleton_method(rb_cPrime, "prime?", prime_is_value_prime, -1);<br>
+}<br>
diff --git lib/prime.rb lib/prime.rb<br>
deleted file mode 100644<br>
index a40d90e..0000000<br>
--- lib/prime.rb<br>
+++ /dev/null<br>
@@ -1,495 +0,0 @@<br>
-#<br>
-# = prime.rb<br>
-#<br>
-# Prime numbers and factorization library.<br>
-#<br>
-# Copyright::<br>
-# Copyright (c) 1998-2008 Keiju ISHITSUKA(SHL Japan Inc.)<br>
-# Copyright (c) 2008 Yuki Sonoda (Yugui) <a href="mailto:yugui@yugui.jp" class="email">yugui@yugui.jp</a><br>
-#<br>
-# Documentation::<br>
-# Yuki Sonoda<br>
-#</li>
</ul>
<ul>
<li>
</ul>
<h2>-require "singleton"<br>
-require "forwardable"</h2>
<p>-class Integer</p>
<ul>
<li>
<a name="Re-composes-a-prime-factorization-and-returns-the-product-3"></a>
<h1 >Re-composes a prime factorization and returns the product.<a href="#Re-composes-a-prime-factorization-and-returns-the-product-3" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="See-Primeint_from_prime_division-for-more-details-2"></a>
<h1 >See Prime#int_from_prime_division for more details.<a href="#See-Primeint_from_prime_division-for-more-details-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def Integer.from_prime_division(pd)</li>
<li>Prime.int_from_prime_division(pd)</li>
<li>end</li>
<li>
<li>
<a name="Returns-the-factorization-of-self-2"></a>
<h1 >Returns the factorization of +self+.<a href="#Returns-the-factorization-of-self-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="See-Primeprime_division-for-more-details-2"></a>
<h1 >See Prime#prime_division for more details.<a href="#See-Primeprime_division-for-more-details-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def prime_division(generator = Prime::Generator23.new)</li>
<li>Prime.prime_division(self, generator)</li>
<li>end</li>
<li>
<li>
<a name="Returns-true-if-self-is-a-prime-number-false-for-a-composite-2"></a>
<h1 >Returns true if +self+ is a prime number, false for a composite.<a href="#Returns-true-if-self-is-a-prime-number-false-for-a-composite-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def prime?</li>
<li>Prime.prime?(self)</li>
<li>end</li>
<li>
<li>
<a name="Iterates-the-given-block-over-all-prime-numbers-3"></a>
<h1 >Iterates the given block over all prime numbers.<a href="#Iterates-the-given-block-over-all-prime-numbers-3" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="See-Primeeach-for-more-details-2"></a>
<h1 >See +Prime+#each for more details.<a href="#See-Primeeach-for-more-details-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def Integer.each_prime(ubound, &block) # :yields: prime</li>
<li>Prime.each(ubound, &block)</li>
<li>end<br>
-end</li>
<li>
</ul>
<p>-#<br>
-# The set of all prime numbers.<br>
-#<br>
-# == Example<br>
-# Prime.each(100) do |prime|<br>
-# p prime #=> 2, 3, 5, 7, 11, ...., 97<br>
-# end<br>
-#<br>
-# == Retrieving the instance<br>
-# +Prime+.new is obsolete. Now +Prime+ has the default instance and you can<br>
-# access it as +Prime+.instance.<br>
-#<br>
-# For convenience, each instance method of +Prime+.instance can be accessed<br>
-# as a class method of +Prime+.<br>
-#<br>
-# e.g.<br>
-# Prime.instance.prime?(2) #=> true<br>
-# Prime.prime?(2) #=> true<br>
-#<br>
-# == Generators<br>
-# A "generator" provides an implementation of enumerating pseudo-prime<br>
-# numbers and it remembers the position of enumeration and upper bound.<br>
-# Futhermore, it is a external iterator of prime enumeration which is<br>
-# compatible to an Enumerator.<br>
-#<br>
-# +Prime+::+PseudoPrimeGenerator+ is the base class for generators.<br>
-# There are few implementations of generator.<br>
-#<br>
-# [+Prime+::+EratosthenesGenerator+]<br>
-# Uses eratosthenes's sieve.<br>
-# [+Prime+::+TrialDivisionGenerator+]<br>
-# Uses the trial division method.<br>
-# [+Prime+::+Generator23+]<br>
-# Generates all positive integers which is not divided by 2 nor 3.<br>
-# This sequence is very bad as a pseudo-prime sequence. But this<br>
-# is faster and uses much less memory than other generators. So,<br>
-# it is suitable for factorizing an integer which is not large but<br>
-# has many prime factors. e.g. for Prime#prime? .<br>
-class Prime</p>
<ul>
<li>include Enumerable</li>
<li>@the_instance = Prime.new</li>
<li>
<li>
<a name="obsolete-Use-Primeinstance-or-class-methods-of-Prime-2"></a>
<h1 >obsolete. Use +Prime+::+instance+ or class methods of +Prime+.<a href="#obsolete-Use-Primeinstance-or-class-methods-of-Prime-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def initialize</li>
<li>@generator = EratosthenesGenerator.new</li>
<li>extend OldCompatibility</li>
<li>warn "Prime::new is obsolete. use Prime::instance or class methods of Prime."</li>
<li>end</li>
<li>
<li>class << self</li>
<li>extend Forwardable</li>
<li>include Enumerable</li>
<li>
<a name="Returns-the-default-instance-of-Prime-2"></a>
<h1 >Returns the default instance of Prime.<a href="#Returns-the-default-instance-of-Prime-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def instance; @the_instance end</li>
<li>
<li>def method_added(method) # :nodoc:</li>
<li>
<pre><code> (class<< self;self;end).def_delegator :instance, method
</code></pre>
</li>
<li>end</li>
<li>end</li>
<li>
<li>
<a name="Iterates-the-given-block-over-all-prime-numbers-4"></a>
<h1 >Iterates the given block over all prime numbers.<a href="#Iterates-the-given-block-over-all-prime-numbers-4" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Parameters-5"></a>
<h1 >== Parameters<a href="#-Parameters-5" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="ubound-3"></a>
<h1 >+ubound+::<a href="#ubound-3" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="Optional-An-arbitrary-positive-number-2"></a>
<h1 >Optional. An arbitrary positive number.<a href="#Optional-An-arbitrary-positive-number-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="The-upper-bound-of-enumeration-The-method-enumerates-2"></a>
<h1 >The upper bound of enumeration. The method enumerates<a href="#The-upper-bound-of-enumeration-The-method-enumerates-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="prime-numbers-infinitely-if-ubound-is-nil-2"></a>
<h1 >prime numbers infinitely if +ubound+ is nil.<a href="#prime-numbers-infinitely-if-ubound-is-nil-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="generator-2"></a>
<h1 >+generator+::<a href="#generator-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="Optional-An-implementation-of-pseudo-prime-generator-2"></a>
<h1 >Optional. An implementation of pseudo-prime generator.<a href="#Optional-An-implementation-of-pseudo-prime-generator-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Return-value-2"></a>
<h1 >== Return value<a href="#-Return-value-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="An-evaluated-value-of-the-given-block-at-the-last-time-2"></a>
<h1 >An evaluated value of the given block at the last time.<a href="#An-evaluated-value-of-the-given-block-at-the-last-time-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="Or-an-enumerator-which-is-compatible-to-an-Enumerator-2"></a>
<h1 >Or an enumerator which is compatible to an +Enumerator+<a href="#Or-an-enumerator-which-is-compatible-to-an-Enumerator-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="if-no-block-given-2"></a>
<h1 >if no block given.<a href="#if-no-block-given-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Description-2"></a>
<h1 >== Description<a href="#-Description-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="Calls-block-once-for-each-prime-number-passing-the-prime-as-2"></a>
<h1 >Calls +block+ once for each prime number, passing the prime as<a href="#Calls-block-once-for-each-prime-number-passing-the-prime-as-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="a-parameter-2"></a>
<h1 >a parameter.<a href="#a-parameter-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="ubound-4"></a>
<h1 >+ubound+::<a href="#ubound-4" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="Upper-bound-of-prime-numbers-The-iterator-stops-after-2"></a>
<h1 >Upper bound of prime numbers. The iterator stops after<a href="#Upper-bound-of-prime-numbers-The-iterator-stops-after-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="yields-all-prime-numbers-p-lt-ubound-2"></a>
<h1 >yields all prime numbers p <= +ubound+.<a href="#yields-all-prime-numbers-p-lt-ubound-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Note-2"></a>
<h1 >== Note<a href="#-Note-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="Primenew-returns-a-object-extended-by-PrimeOldCompatibility-2"></a>
<h1 >+Prime+.+new+ returns a object extended by +Prime+::+OldCompatibility+<a href="#Primenew-returns-a-object-extended-by-PrimeOldCompatibility-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="in-order-to-compatibility-to-Ruby-18-and-Primeeach-is-overwritten-2"></a>
<h1 >in order to compatibility to Ruby 1.8, and +Prime+#each is overwritten<a href="#in-order-to-compatibility-to-Ruby-18-and-Primeeach-is-overwritten-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="by-PrimeOldCompatibilityeach-2"></a>
<h1 >by +Prime+::+OldCompatibility+#+each+.<a href="#by-PrimeOldCompatibilityeach-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="Primenew-is-now-obsolete-Use-Primeinstanceeach-or-simply-2"></a>
<h1 >+Prime+.+new+ is now obsolete. Use +Prime+.+instance+.+each+ or simply<a href="#Primenew-is-now-obsolete-Use-Primeinstanceeach-or-simply-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="Primeeach-2"></a>
<h1 >+Prime+.+each+.<a href="#Primeeach-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def each(ubound = nil, generator = EratosthenesGenerator.new, &block)</li>
<li>generator.upper_bound = ubound</li>
<li>generator.each(&block)</li>
<li>end</li>
<li>
<li>
<li>
<a name="Returns-true-if-value-is-prime-false-for-a-composite-2"></a>
<h1 >Returns true if +value+ is prime, false for a composite.<a href="#Returns-true-if-value-is-prime-false-for-a-composite-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Parameters-6"></a>
<h1 >== Parameters<a href="#-Parameters-6" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="value-an-arbitrary-integer-to-be-checked-2"></a>
<h1 >+value+:: an arbitrary integer to be checked.<a href="#value-an-arbitrary-integer-to-be-checked-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="generator-optional-A-pseudo-prime-generator-2"></a>
<h1 >+generator+:: optional. A pseudo-prime generator.<a href="#generator-optional-A-pseudo-prime-generator-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def prime?(value, generator = Prime::Generator23.new)</li>
<li>value = -value if value < 0</li>
<li>return false if value < 2</li>
<li>for num in generator</li>
<li>
<pre><code> q,r = value.divmod num
</code></pre>
</li>
<li>
<pre><code> return true if q < num
</code></pre>
</li>
<li>
<pre><code> return false if r == 0
</code></pre>
</li>
<li>end</li>
<li>end</li>
<li>
<li>
<a name="Re-composes-a-prime-factorization-and-returns-the-product-4"></a>
<h1 >Re-composes a prime factorization and returns the product.<a href="#Re-composes-a-prime-factorization-and-returns-the-product-4" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Parameters-7"></a>
<h1 >== Parameters<a href="#-Parameters-7" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="pd-Array-of-pairs-of-integers-The-each-internal-2"></a>
<h1 >+pd+:: Array of pairs of integers. The each internal<a href="#pd-Array-of-pairs-of-integers-The-each-internal-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="pair-consists-of-a-prime-number-a-prime-factor--2"></a>
<h1 >pair consists of a prime number -- a prime factor --<a href="#pair-consists-of-a-prime-number-a-prime-factor--2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="and-a-natural-number-an-exponent-2"></a>
<h1 >and a natural number -- an exponent.<a href="#and-a-natural-number-an-exponent-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Example-3"></a>
<h1 >== Example<a href="#-Example-3" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="For-p_1-e_1-p_2-e_2-p_n-e_n-it-returns-2"></a>
<h1 >For [[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]], it returns<a href="#For-p_1-e_1-p_2-e_2-p_n-e_n-it-returns-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="p_1e_1-p_2e_2-p_ne_n-2"></a>
<h1 >p_1<strong>e_1 * p_2</strong>e_2 * .... * p_n**e_n.<a href="#p_1e_1-p_2e_2-p_ne_n-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="Primeint_from_prime_division22-31-gt-12-2"></a>
<h1 >Prime.int_from_prime_division([[2,2], [3,1]]) #=> 12<a href="#Primeint_from_prime_division22-31-gt-12-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def int_from_prime_division(pd)</li>
<li>pd.inject(1){|value, (prime, index)|</li>
<li>
<pre><code> value *= prime**index
</code></pre>
</li>
<li>}</li>
<li>end</li>
<li>
<li>
<a name="Returns-the-factorization-of-value-2"></a>
<h1 >Returns the factorization of +value+.<a href="#Returns-the-factorization-of-value-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Parameters-8"></a>
<h1 >== Parameters<a href="#-Parameters-8" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="value-An-arbitrary-integer-2"></a>
<h1 >+value+:: An arbitrary integer.<a href="#value-An-arbitrary-integer-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="generator-Optional-A-pseudo-prime-generator-2"></a>
<h1 >+generator+:: Optional. A pseudo-prime generator.<a href="#generator-Optional-A-pseudo-prime-generator-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="generatorsucc-must-return-the-next-2"></a>
<h1 >+generator+.succ must return the next<a href="#generatorsucc-must-return-the-next-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="pseudo-prime-number-in-the-ascendent-2"></a>
<h1 >pseudo-prime number in the ascendent<a href="#pseudo-prime-number-in-the-ascendent-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="order-It-must-generate-all-prime-numbers-2"></a>
<h1 >order. It must generate all prime numbers,<a href="#order-It-must-generate-all-prime-numbers-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="but-may-generate-non-prime-numbers-2"></a>
<h1 >but may generate non prime numbers.<a href="#but-may-generate-non-prime-numbers-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Exceptions-2"></a>
<h1 >=== Exceptions<a href="#-Exceptions-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="ZeroDivisionError-when-value-is-zero-2"></a>
<h1 >+ZeroDivisionError+:: when +value+ is zero.<a href="#ZeroDivisionError-when-value-is-zero-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="-Example-4"></a>
<h1 >== Example<a href="#-Example-4" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="For-an-arbitrary-integer-2"></a>
<h1 >For an arbitrary integer<a href="#For-an-arbitrary-integer-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="n-p_1e_1-p_2e_2-p_ne_n-2"></a>
<h1 >n = p_1<strong>e_1 * p_2</strong>e_2 * .... * p_n**e_n,<a href="#n-p_1e_1-p_2e_2-p_ne_n-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="prime_divisionn-returns-2"></a>
<h1 >prime_division(n) returns<a href="#prime_divisionn-returns-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="p_1-e_1-p_2-e_2-p_n-e_n-2"></a>
<h1 >[[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]].<a href="#p_1-e_1-p_2-e_2-p_n-e_n-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="Primeprime_division12-gt-22-31-2"></a>
<h1 >Prime.prime_division(12) #=> [[2,2], [3,1]]<a href="#Primeprime_division12-gt-22-31-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>def prime_division(value, generator= Prime::Generator23.new)</li>
<li>raise ZeroDivisionError if value == 0</li>
<li>if value < 0</li>
<li>
<pre><code> value = -value
</code></pre>
</li>
<li>
<pre><code> pv = [[-1, 1]]
</code></pre>
</li>
<li>else</li>
<li>
<pre><code> pv = []
</code></pre>
</li>
<li>end</li>
<li>for prime in generator</li>
<li>
<pre><code> count = 0
</code></pre>
</li>
<li>
<pre><code> while (value1, mod = value.divmod(prime)
</code></pre>
</li>
<li>
<pre><code> mod) == 0
</code></pre>
</li>
<li>value = value1</li>
<li>count += 1</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> if count != 0
</code></pre>
</li>
<li>pv.push [prime, count]</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> break if value1 <= prime
</code></pre>
</li>
<li>end</li>
<li>if value > 1</li>
<li>
<pre><code> pv.push [value, 1]
</code></pre>
</li>
<li>end</li>
<li>return pv</li>
<li>end</li>
<li>
<li>
<a name="An-abstract-class-for-enumerating-pseudo-prime-numbers-2"></a>
<h1 >An abstract class for enumerating pseudo-prime numbers.<a href="#An-abstract-class-for-enumerating-pseudo-prime-numbers-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="Concrete-subclasses-should-override-succ-next-rewind-2"></a>
<h1 >Concrete subclasses should override succ, next, rewind.<a href="#Concrete-subclasses-should-override-succ-next-rewind-2" class="wiki-anchor">¶</a></h1>
</li>
<li>class PseudoPrimeGenerator</li>
<li>include Enumerable</li>
<li>
<li>def initialize(ubound = nil)</li>
<li>
<pre><code> @ubound = ubound
</code></pre>
</li>
<li>end</li>
<li>
<li>def upper_bound=(ubound)</li>
<li>
<pre><code> @ubound = ubound
</code></pre>
</li>
<li>end</li>
<li>def upper_bound</li>
<li>
<pre><code> @ubound
</code></pre>
</li>
<li>end</li>
<li>
<li>
<a name="returns-the-next-pseudo-prime-number-and-move-the-internal-2"></a>
<h1 >returns the next pseudo-prime number, and move the internal<a href="#returns-the-next-pseudo-prime-number-and-move-the-internal-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="position-forward-2"></a>
<h1 >position forward.<a href="#position-forward-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="PseudoPrimeGeneratorsucc-raises-NotImplementedError-2"></a>
<h1 >+PseudoPrimeGenerator+#succ raises +NotImplementedError+.<a href="#PseudoPrimeGeneratorsucc-raises-NotImplementedError-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def succ</li>
<li>
<pre><code> raise NotImplementedError, "need to define `succ'"
</code></pre>
</li>
<li>end</li>
<li>
<li>
<a name="alias-of-succ-2"></a>
<h1 >alias of +succ+.<a href="#alias-of-succ-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def next</li>
<li>
<pre><code> raise NotImplementedError, "need to define `next'"
</code></pre>
</li>
<li>end</li>
<li>
<li>
<a name="Rewinds-the-internal-position-for-enumeration-2"></a>
<h1 >Rewinds the internal position for enumeration.<a href="#Rewinds-the-internal-position-for-enumeration-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="See-Enumeratorrewind-2"></a>
<h1 >See +Enumerator+#rewind.<a href="#See-Enumeratorrewind-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def rewind</li>
<li>
<pre><code> raise NotImplementedError, "need to define `rewind'"
</code></pre>
</li>
<li>end</li>
<li>
<li>
<a name="Iterates-the-given-block-for-each-prime-numbers-2"></a>
<h1 >Iterates the given block for each prime numbers.<a href="#Iterates-the-given-block-for-each-prime-numbers-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def each(&block)</li>
<li>
<pre><code> return self.dup unless block
</code></pre>
</li>
<li>
<pre><code> if @ubound
</code></pre>
</li>
<li>last_value = nil</li>
<li>loop do</li>
<li>prime = succ</li>
<li>break last_value if prime > @ubound</li>
<li>last_value = block.call(prime)</li>
<li>end</li>
<li>
<pre><code> else
</code></pre>
</li>
<li>loop do</li>
<li>block.call(succ)</li>
<li>end</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>end</li>
<li>
<li>
<a name="see-Enumeratorwith_index-2"></a>
<h1 >see +Enumerator+#with_index.<a href="#see-Enumeratorwith_index-2" class="wiki-anchor">¶</a></h1>
</li>
<li>alias with_index each_with_index</li>
<li>
<li>
<a name="see-Enumeratorwith_object-2"></a>
<h1 >see +Enumerator+#with_object.<a href="#see-Enumeratorwith_object-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def with_object(obj)</li>
<li>
<pre><code> return enum_for(:with_object) unless block_given?
</code></pre>
</li>
<li>
<pre><code> each do |prime|
</code></pre>
</li>
<li>yield prime, obj</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>end</li>
<li>end</li>
<li>
<li>
<a name="An-implementation-of-PseudoPrimeGenerator-2"></a>
<h1 >An implementation of +PseudoPrimeGenerator+.<a href="#An-implementation-of-PseudoPrimeGenerator-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="Uses-EratosthenesSieve-2"></a>
<h1 >Uses +EratosthenesSieve+.<a href="#Uses-EratosthenesSieve-2" class="wiki-anchor">¶</a></h1>
</li>
<li>class EratosthenesGenerator < PseudoPrimeGenerator</li>
<li>def initialize</li>
<li>
<pre><code> @last_prime = nil
</code></pre>
</li>
<li>
<pre><code> super
</code></pre>
</li>
<li>end</li>
<li>
<li>def succ</li>
<li>
<pre><code> @last_prime = @last_prime ? EratosthenesSieve.instance.next_to(@last_prime) : 2
</code></pre>
</li>
<li>end</li>
<li>def rewind</li>
<li>
<pre><code> initialize
</code></pre>
</li>
<li>end</li>
<li>alias next succ</li>
<li>end</li>
<li>
<li>
<a name="An-implementation-of-PseudoPrimeGenerator-which-uses-2"></a>
<h1 >An implementation of +PseudoPrimeGenerator+ which uses<a href="#An-implementation-of-PseudoPrimeGenerator-which-uses-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="a-prime-table-generated-by-trial-division-2"></a>
<h1 >a prime table generated by trial division.<a href="#a-prime-table-generated-by-trial-division-2" class="wiki-anchor">¶</a></h1>
</li>
<li>class TrialDivisionGenerator<PseudoPrimeGenerator</li>
<li>def initialize</li>
<li>
<pre><code> @index = -1
</code></pre>
</li>
<li>
<pre><code> super
</code></pre>
</li>
<li>end</li>
<li>
<li>def succ</li>
<li>
<pre><code> TrialDivision.instance[@index += 1]
</code></pre>
</li>
<li>end</li>
<li>def rewind</li>
<li>
<pre><code> initialize
</code></pre>
</li>
<li>end</li>
<li>alias next succ</li>
<li>end</li>
<li>
<li>
<a name="Generates-all-integer-which-are-greater-than-2-and-2"></a>
<h1 >Generates all integer which are greater than 2 and<a href="#Generates-all-integer-which-are-greater-than-2-and-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="are-not-divided-by-2-nor-3-2"></a>
<h1 >are not divided by 2 nor 3.<a href="#are-not-divided-by-2-nor-3-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="This-is-a-pseudo-prime-generator-suitable-on-2"></a>
<h1 >This is a pseudo-prime generator, suitable on<a href="#This-is-a-pseudo-prime-generator-suitable-on-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="checking-primality-of-a-integer-by-brute-force-2"></a>
<h1 >checking primality of a integer by brute force<a href="#checking-primality-of-a-integer-by-brute-force-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="method-2"></a>
<h1 >method.<a href="#method-2" class="wiki-anchor">¶</a></h1>
</li>
<li>class Generator23<PseudoPrimeGenerator</li>
<li>def initialize</li>
<li>
<pre><code> @prime = 1
</code></pre>
</li>
<li>
<pre><code> @step = nil
</code></pre>
</li>
<li>
<pre><code> super
</code></pre>
</li>
<li>end</li>
<li>
<li>def succ</li>
<li>
<pre><code> loop do
</code></pre>
</li>
<li>if (@step)</li>
<li>@prime += @step</li>
<li>@step = 6 - @step</li>
<li>else</li>
<li>case @prime</li>
<li>when 1; @prime = 2</li>
<li>when 2; @prime = 3</li>
<li>when 3; @prime = 5; @step = 2</li>
<li>end</li>
<li>end</li>
<li>return @prime</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>end</li>
<li>alias next succ</li>
<li>def rewind</li>
<li>
<pre><code> initialize
</code></pre>
</li>
<li>end</li>
<li>end</li>
<li>
<li>
<li>
<li>
<li>
<a name="Internal-use-An-implementation-of-prime-table-by-trial-division-method-2"></a>
<h1 >Internal use. An implementation of prime table by trial division method.<a href="#Internal-use-An-implementation-of-prime-table-by-trial-division-method-2" class="wiki-anchor">¶</a></h1>
</li>
<li>class TrialDivision</li>
<li>include Singleton</li>
<li>
<li>def initialize # :nodoc:</li>
<li>
<pre><code> # These are included as class variables to cache them for later uses. If memory
</code></pre>
</li>
<li>
<pre><code> # usage is a problem, they can be put in Prime#initialize as instance variables.
</code></pre>
</li>
<li>
<li>
<pre><code> # There must be no primes between @primes[-1] and @next_to_check.
</code></pre>
</li>
<li>
<pre><code> @primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101]
</code></pre>
</li>
<li>
<pre><code> # @next_to_check % 6 must be 1.
</code></pre>
</li>
<li>
<pre><code> @next_to_check = 103 # @primes[-1] - @primes[-1] % 6 + 7
</code></pre>
</li>
<li>
<pre><code> @ulticheck_index = 3 # @primes.index(@primes.reverse.find {|n|
</code></pre>
</li>
<li>
<pre><code> # n < Math.sqrt(@@next_to_check) })
</code></pre>
</li>
<li>
<pre><code> @ulticheck_next_squared = 121 # @primes[@ulticheck_index + 1] ** 2
</code></pre>
</li>
<li>end</li>
<li>
<li>
<a name="Returns-the-cached-prime-numbers-2"></a>
<h1 >Returns the cached prime numbers.<a href="#Returns-the-cached-prime-numbers-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def cache</li>
<li>
<pre><code> return @primes
</code></pre>
</li>
<li>end</li>
<li>alias primes cache</li>
<li>alias primes_so_far cache</li>
<li>
<li>
<a name="Returns-the-indexth-prime-number-2"></a>
<h1 >Returns the +index+th prime number.<a href="#Returns-the-indexth-prime-number-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="index-is-a-0-based-index-2"></a>
<h1 >+index+ is a 0-based index.<a href="#index-is-a-0-based-index-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def <a href="index"></a>
</li>
<li>
<pre><code> while index >= @primes.length
</code></pre>
</li>
<li>
<a name="Only-check-for-prime-factors-up-to-the-square-root-of-the-potential-primes-2"></a>
<h1 >Only check for prime factors up to the square root of the potential primes,<a href="#Only-check-for-prime-factors-up-to-the-square-root-of-the-potential-primes-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="but-without-the-performance-hit-of-an-actual-square-root-calculation-2"></a>
<h1 >but without the performance hit of an actual square root calculation.<a href="#but-without-the-performance-hit-of-an-actual-square-root-calculation-2" class="wiki-anchor">¶</a></h1>
</li>
<li>if @next_to_check + 4 > @ulticheck_next_squared</li>
<li>@ulticheck_index += 1</li>
<li>@ulticheck_next_squared = @primes.at(@ulticheck_index + 1) ** 2</li>
<li>end</li>
<li>
<a name="Only-check-numbers-congruent-to-one-and-five-modulo-six-All-others-2"></a>
<h1 >Only check numbers congruent to one and five, modulo six. All others<a href="#Only-check-numbers-congruent-to-one-and-five-modulo-six-All-others-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<li>
<a name="are-divisible-by-two-or-three-This-also-allows-us-to-skip-checking-against-2"></a>
<h1 >are divisible by two or three. This also allows us to skip checking against<a href="#are-divisible-by-two-or-three-This-also-allows-us-to-skip-checking-against-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="two-and-three-2"></a>
<h1 >two and three.<a href="#two-and-three-2" class="wiki-anchor">¶</a></h1>
</li>
<li>@primes.push @next_to_check if @primes[2..@ulticheck_index].find {|prime| @next_to_check % prime == 0 }.nil?</li>
<li>@next_to_check += 4</li>
<li>@primes.push @next_to_check if @primes[2..@ulticheck_index].find {|prime| @next_to_check % prime == 0 }.nil?</li>
<li>@next_to_check += 2</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> return @primes[index]
</code></pre>
</li>
<li>end</li>
<li>end</li>
<li>
<li>
<a name="Internal-use-An-implementation-of-eratostheness-sieve-2"></a>
<h1 >Internal use. An implementation of eratosthenes's sieve<a href="#Internal-use-An-implementation-of-eratostheness-sieve-2" class="wiki-anchor">¶</a></h1>
</li>
<li>class EratosthenesSieve</li>
<li>include Singleton</li>
<li>
<li>BITS_PER_ENTRY = 16 # each entry is a set of 16-bits in a Fixnum</li>
<li>NUMS_PER_ENTRY = BITS_PER_ENTRY * 2 # twiced because even numbers are omitted</li>
<li>ENTRIES_PER_TABLE = 8</li>
<li>NUMS_PER_TABLE = NUMS_PER_ENTRY * ENTRIES_PER_TABLE</li>
<li>FILLED_ENTRY = (1 << NUMS_PER_ENTRY) - 1</li>
<li>
<li>def initialize # :nodoc:</li>
<li>
<pre><code> # bitmap for odd prime numbers less than 256.
</code></pre>
</li>
<li>
<pre><code> # For an arbitrary odd number n, @tables[i][j][k] is
</code></pre>
</li>
<li>
<pre><code> # * 1 if n is prime,
</code></pre>
</li>
<li>
<pre><code> # * 0 if n is composite,
</code></pre>
</li>
<li>
<pre><code> # where i,j,k = indices(n)
</code></pre>
</li>
<li>
<pre><code> @tables = [[0xcb6e, 0x64b4, 0x129a, 0x816d, 0x4c32, 0x864a, 0x820d, 0x2196].freeze]
</code></pre>
</li>
<li>end</li>
<li>
<li>
<a name="returns-the-least-odd-prime-number-which-is-greater-than-n-2"></a>
<h1 >returns the least odd prime number which is greater than +n+.<a href="#returns-the-least-odd-prime-number-which-is-greater-than-n-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def next_to(n)</li>
<li>
<pre><code> n = (n-1).div(2)*2+3 # the next odd number to given n
</code></pre>
</li>
<li>
<pre><code> table_index, integer_index, bit_index = indices(n)
</code></pre>
</li>
<li>
<pre><code> loop do
</code></pre>
</li>
<li>extend_table until @tables.length > table_index</li>
<li>for j in integer_index...ENTRIES_PER_TABLE</li>
<li>if !@tables[table_index][j].zero?</li>
<li>
<pre><code> for k in bit_index...BITS_PER_ENTRY
</code></pre>
</li>
<li>
<pre><code> return NUMS_PER_TABLE*table_index + NUMS_PER_ENTRY*j + 2*k+1 if !@tables[table_index][j][k].zero?
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>end</li>
<li>bit_index = 0</li>
<li>end</li>
<li>table_index += 1; integer_index = 0</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>end</li>
<li>
<li>private</li>
<li>
<a name="for-an-odd-number-n-returns-i-j-k-such-that-tablesijk-represents-primarity-of-the-number-2"></a>
<h1 >for an odd number +n+, returns (i, j, k) such that @tables[i][j][k] represents primarity of the number<a href="#for-an-odd-number-n-returns-i-j-k-such-that-tablesijk-represents-primarity-of-the-number-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def indices(n)</li>
<li>
<pre><code> # binary digits of n: |0|1|2|3|4|5|6|7|8|9|10|11|....
</code></pre>
</li>
<li>
<pre><code> # indices: |-| k | j | i
</code></pre>
</li>
<li>
<pre><code> # because of NUMS_PER_ENTRY, NUMS_PER_TABLE
</code></pre>
</li>
<li>
<li>
<pre><code> k = (n & 0b00011111) >> 1
</code></pre>
</li>
<li>
<pre><code> j = (n & 0b11100000) >> 5
</code></pre>
</li>
<li>
<pre><code> i = n >> 8
</code></pre>
</li>
<li>
<pre><code> return i, j, k
</code></pre>
</li>
<li>end</li>
<li>
<li>def extend_table</li>
<li>
<pre><code> lbound = NUMS_PER_TABLE * @tables.length
</code></pre>
</li>
<li>
<pre><code> ubound = lbound + NUMS_PER_TABLE
</code></pre>
</li>
<li>
<pre><code> new_table = [FILLED_ENTRY] * ENTRIES_PER_TABLE # which represents primarity in lbound...ubound
</code></pre>
</li>
<li>
<pre><code> (3..Integer(Math.sqrt(ubound))).step(2) do |p|
</code></pre>
</li>
<li>i, j, k = indices(p)</li>
<li>next if @tables[i][j][k].zero?</li>
<li>
<li>start = (lbound.div(p)+1)*p # least multiple of p which is >= lbound</li>
<li>start += p if start.even?</li>
<li>(start...ubound).step(2*p) do |n|</li>
<li>_, j, k = indices(n)</li>
<li>new_table[j] &= FILLED_ENTRY^(1<<k)</li>
<li>end</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> @tables << new_table.freeze
</code></pre>
</li>
<li>end</li>
<li>end</li>
<li>
<li>
<a name="Provides-a-Prime-object-with-compatibility-to-Ruby-18-when-instantiated-via-Primenew-2"></a>
<h1 >Provides a +Prime+ object with compatibility to Ruby 1.8 when instantiated via +Prime+.+new+.<a href="#Provides-a-Prime-object-with-compatibility-to-Ruby-18-when-instantiated-via-Primenew-2" class="wiki-anchor">¶</a></h1>
</li>
<li>module OldCompatibility</li>
<li>
<a name="Returns-the-next-prime-number-and-forwards-internal-pointer-2"></a>
<h1 >Returns the next prime number and forwards internal pointer.<a href="#Returns-the-next-prime-number-and-forwards-internal-pointer-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def succ</li>
<li>
<pre><code> @generator.succ
</code></pre>
</li>
<li>end</li>
<li>alias next succ</li>
<li>
<li>
<a name="Overwrites-Primeeach-2"></a>
<h1 >Overwrites Prime#each.<a href="#Overwrites-Primeeach-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>
<a name="Iterates-the-given-block-over-all-prime-numbers-Note-that-enumeration-starts-from-2"></a>
<h1 >Iterates the given block over all prime numbers. Note that enumeration starts from<a href="#Iterates-the-given-block-over-all-prime-numbers-Note-that-enumeration-starts-from-2" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="the-current-position-of-internal-pointer-not-rewound-2"></a>
<h1 >the current position of internal pointer, not rewound.<a href="#the-current-position-of-internal-pointer-not-rewound-2" class="wiki-anchor">¶</a></h1>
</li>
<li>def each(&block)</li>
<li>
<pre><code> return @generator.dup unless block_given?
</code></pre>
</li>
<li>
<pre><code> loop do
</code></pre>
</li>
<li>yield succ</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>end</li>
<li>end<br>
-end<br>
diff --git test/test_prime.rb test/test_prime.rb<br>
index e095a29..eba8bcd 100644<br>
--- test/test_prime.rb<br>
+++ test/test_prime.rb<br>
@@ -95,6 +95,13 @@ class TestPrime < Test::Unit::TestCase<br>
assert !Prime.instance.respond_to?(:next)<br>
end</li>
</ul>
<ul>
<li>def test_prime?</li>
<li>
<a name="force-use-PrimeGenerator23-for-generator"></a>
<h1 >force use Prime::Generator23 for generator<a href="#force-use-PrimeGenerator23-for-generator" class="wiki-anchor">¶</a></h1>
</li>
<li>assert !Prime.prime?(0,Prime::Generator23.new)</li>
<li>assert !Prime.prime?(1,Prime::Generator23.new)</li>
<li>assert Prime.prime?(7,Prime::Generator23.new)</li>
<li>end</li>
<li>class TestInteger < Test::Unit::TestCase<br>
def test_prime_division<br>
pd = PRIMES.inject(&:*).prime_division<br>
=end</li>
</ul>
Ruby master - Bug #3590 (Closed): RubyGems is Broken
https://bugs.ruby-lang.org/issues/3590
2010-07-21T10:17:37Z
sorah (Sorah Fukumori)
her@sorah.jp
<p>=begin<br>
Hi,</p>
<p>Rubygems is broken in ruby 1.9.3dev.<br>
This problem can occur in any gems (I expect).</p>
<p>--<br>
The following code reproduces this problem:</p>
<p>begin # Can't load active_record<br>
p require 'active_record'<br>
rescue LoadError => e<br>
p e<br>
end<br>
p ActiveRecord rescue p $! # So it's raise NameError.</p>
<p>p require 'rubygems'<br>
begin # Can load after require 'rubygems'<br>
p require 'active_record' #it returns true<br>
rescue LoadError => e<br>
p e<br>
end<br>
p ActiveRecord rescue p $! #but NameError is raised.</p>
<hr>
<p>And the result of that code in r28695:</p>
<p>#<LoadError: cannot load such file -- active_record><br>
#<NameError: uninitialized constant ActiveRecord><br>
false<br>
true<br>
#<NameError: uninitialized constant ActiveRecord></p>
<hr>
<p>In a reference, this is result of that code in ruby1.9.1:</p>
<p>true<br>
ActiveRecord<br>
false<br>
false<br>
ActiveRecord</p>
<hr>
<p>And more result (ruby -d) available in here: <a href="http://gist.github.com/483826" class="external">http://gist.github.com/483826</a><br>
=end</p>