Ruby Issue Tracking System: Issues
https://redmine.ruby-lang.org/
https://redmine.ruby-lang.org/favicon.ico?1711330511
2019-06-25T13:12:18Z
Ruby Issue Tracking System
Redmine
Ruby master - Feature #15958 (Closed): Time#inspect with frac
https://redmine.ruby-lang.org/issues/15958
2019-06-25T13:12:18Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>When Matz changed Time#to_s format in 2006, frac part of Time string is dropped because it is considered not useful.<br>
<a href="https://blade.ruby-lang.org/ruby-dev/29440">[ruby-dev:29440]</a></p>
<p>But recently we encounters some troubles the comparison of Time objects whose frac parts are different.<br>
<a href="https://twitter.com/__gfx__/status/1143056072422219776" class="external">https://twitter.com/__gfx__/status/1143056072422219776</a></p>
<p>For example a is original object and b is once stored in RDB (and dropped the frac part).<br>
Or there're multiple time objects which are generated in a single HTTP request.<br>
Of course they are different and assert_equal will be failed but inspect doesn't show the frac part.</p>
Ruby master - Misc #14861 (Closed): DevelopersMeeting20180718Japan
https://redmine.ruby-lang.org/issues/14861
2018-06-21T05:58:04Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Date: 2018/07/18 (Thu)<br>
Time: 14:00-18:00 (JST)<br>
Place: MoneyForward HQ (beware: new location) (Tokyo, Japan)<br>
Sign-up: <a href="https://ruby.connpass.com/event/92314/" class="external">https://ruby.connpass.com/event/92314/</a><br>
log: <a href="https://docs.google.com/document/d/1_cKh0LJd18y5CH1MfM6WC1fqh2rpHHZntrBCLTbwRSE/edit" class="external">https://docs.google.com/document/d/1_cKh0LJd18y5CH1MfM6WC1fqh2rpHHZntrBCLTbwRSE/edit</a><br>
pub: <a href="https://docs.google.com/document/d/1_cKh0LJd18y5CH1MfM6WC1fqh2rpHHZntrBCLTbwRSE/pub" class="external">https://docs.google.com/document/d/1_cKh0LJd18y5CH1MfM6WC1fqh2rpHHZntrBCLTbwRSE/pub</a></p>
<p>Please comment your favorite ticket numbers you want to ask to discuss with your <em>SHORT</em> comment or summary.<br>
(your summary/comment will help us because we don't need to read all of ticket comments)</p>
<p><em>DO NOT</em> discuss then on this ticket, please.</p>
<p>Past meetings: <a href="https://bugs.ruby-lang.org/projects/ruby/wiki#Developer-Meetings" class="external">https://bugs.ruby-lang.org/projects/ruby/wiki#Developer-Meetings</a></p>
<a name="NOTE"></a>
<h1 >NOTE<a href="#NOTE" class="wiki-anchor">¶</a></h1>
<p>Dev meeting <em>IS NOT</em> a decision making place. All decisions should be done at the bug tracker.<br>
Dev meeting is a place we can ask Matz, nobu, nurse and other developers directly.<br>
Matz is a very busy person. Take this opportunity to ask him. If you can not attend, other attendees can ask instead of you (if attendees can understand your issue).<br>
We will write a log about discussion to a file or to each ticket in English.<br>
All activities are best-effort (keep in mind that most of us are volunteer developers).<br>
The date, time and place is scheduled according to when/where we can reserve Matz's time.</p>
<a name="Agenda"></a>
<h1 >Agenda<a href="#Agenda" class="wiki-anchor">¶</a></h1>
<a name="Next-dev-meeting"></a>
<h2 >Next dev-meeting<a href="#Next-dev-meeting" class="wiki-anchor">¶</a></h2>
<a name="About-26-timeframe"></a>
<h2 >About 2.6 timeframe<a href="#About-26-timeframe" class="wiki-anchor">¶</a></h2>
<a name="Carry-over-from-previous-meetings"></a>
<h2 >Carry-over from previous meeting(s)<a href="#Carry-over-from-previous-meetings" class="wiki-anchor">¶</a></h2>
<ul>
<li>[Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Comparable#clamp with a range (Closed)" href="https://redmine.ruby-lang.org/issues/14784">#14784</a>] One-sided Comparable#clamp (with endless/startless ranges) (zverok)
<ul>
<li>more reasonable version of Object#enumerate proposed for the previous meeting.</li>
</ul>
</li>
<li>[Feature <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: [PATCH] implement Timeout in VM (Open)" href="https://redmine.ruby-lang.org/issues/14859">#14859</a>] Timeout in VM (normalperson)
<ul>
<li>Still needs some work, mainly wondering if the idea of moving this part of stdlib into core VM is acceptable or not. No semantic changes except speed improvement.</li>
</ul>
</li>
</ul>
<a name="From-Attendees"></a>
<h2 >From Attendees<a href="#From-Attendees" class="wiki-anchor">¶</a></h2>
<p>(will be edited later)<br>
(if you have a write access permission, please list directly)</p>
<ul>
<li>[Bug <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Array#delete_if does not use #delete (Closed)" href="https://redmine.ruby-lang.org/issues/14887">#14887</a>] Array#delete_if does not use #delete (shyouhei)
<ul>
<li>Is it by design, or a bug?</li>
</ul>
</li>
<li>[Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Readline: expose rl_completion_quote_character variable (Closed)" href="https://redmine.ruby-lang.org/issues/13050">#13050</a>] Readline: expose rl_completion_quote_character variable (nobu)</li>
<li>[Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Add official API for setting timezone on Time (Closed)" href="https://redmine.ruby-lang.org/issues/14850">#14850</a>] Add official API for setting timezone on Time (nobu)</li>
<li>[Feature <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Proposal to add Hash#=== (Open)" href="https://redmine.ruby-lang.org/issues/14869">#14869</a>] Proposal to add Hash#=== (nobu)</li>
<li>[Feature <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Calculate age in Date class (Rejected)" href="https://redmine.ruby-lang.org/issues/14877">#14877</a>] Calculate age in Date class (nobu)</li>
<li>[Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Add Range#subrange? (Closed)" href="https://redmine.ruby-lang.org/issues/14473">#14473</a>] Add Range#subrange? (tarui)</li>
<li>[Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Enumerator::Lazy creates unnecessary Array objects. (Closed)" href="https://redmine.ruby-lang.org/issues/14908">#14908</a>] Enumerator::Lazy creates unnecessary Array objects. (nobu)</li>
<li>[Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Introduce pattern matching syntax (Closed)" href="https://redmine.ruby-lang.org/issues/14912">#14912</a>] Introduce pattern matching syntax (mame)
<ul>
<li>pattern matching</li>
</ul>
</li>
<li>opt_to_s (nobu)
<ul>
<li>see below for his patch</li>
</ul>
</li>
<li>[Feature <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Add String#byteslice! (Open)" href="https://redmine.ruby-lang.org/issues/13626">#13626</a>] Add String#byteslice! (aycabta)</li>
<li>[Feature <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Add display width method to String for CLI (Open)" href="https://redmine.ruby-lang.org/issues/14618">#14618</a>] Add display width method to String for CLI (aycabta)</li>
<li>[Misc <a class="issue tracker-5 status-2 priority-4 priority-default" title="Misc: Add RDoc documents to tar ball (Assigned)" href="https://redmine.ruby-lang.org/issues/14917">#14917</a>] Add RDoc documents to tar ball (aycabta)</li>
<li>[Feature <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Use Reline for fallback of ext/readline (Closed)" href="https://redmine.ruby-lang.org/issues/14918">#14918</a>] Use Reline for fallback of ext/readline (aycabta)</li>
<li>[Feature <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Add String#byteinsert (Open)" href="https://redmine.ruby-lang.org/issues/14919">#14919</a>] Add String#byteinsert (aycabta)</li>
<li>[Feature <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Proposal to add Array#=== (Open)" href="https://redmine.ruby-lang.org/issues/14916">#14916</a>] Proposal to add Array#=== (aycabta)</li>
</ul>
<a name="From-non-attendees"></a>
<h2 >From non-attendees<a href="#From-non-attendees" class="wiki-anchor">¶</a></h2>
<p>(will be edited later)<br>
(if you have a write access, please list directly)</p>
<ul>
<li>[Feature <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: ArgumentErrorが発生した時メソッドのプロトタイプをメッセージに含む (Open)" href="https://redmine.ruby-lang.org/issues/14111">#14111</a>] ArgumentErrorが発生した時メソッドのプロトタイプをメッセージに含む (esjee)
<ul>
<li>Suggestion: include method parameters when generating an ArgumentsError message. Nobu's patch in the issue provides functionality to make writing a ruby gem to provide this functionality possible.</li>
</ul>
</li>
<li>[Bug <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Add command line argument to deactivate JIT (Closed)" href="https://redmine.ruby-lang.org/issues/14878">#14878</a>] Add command line argument to deactivate JIT (k0kubun)
<ul>
<li>Please discuss the necessity of the flag and its name in the proposal.</li>
</ul>
</li>
<li>[Feature <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Implement String #blank? #present? and improve #strip and family to handle unicode (Open)" href="https://redmine.ruby-lang.org/issues/12306">#12306</a>] Implement String #blank? #present? and improve #strip and family to handle unicode (sam.saffron)</li>
<li>[Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Extend case to match several values at once (Closed)" href="https://redmine.ruby-lang.org/issues/14913">#14913</a>] Extend case to match several values at once (zverok)
<ul>
<li>some steps towards better pattern matching</li>
</ul>
</li>
<li>[Feature <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Add BasicObject#instance_exec_with_block (Rejected)" href="https://redmine.ruby-lang.org/issues/14914">#14914</a>] Add BasicObject#instance_exec_with_block (jeremyevans0)</li>
<li>[Feature <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Deprecate String#crypt (Rejected)" href="https://redmine.ruby-lang.org/issues/14915">#14915</a>] Deprecate String#crypt, move implementation to string/crypt (jeremyevans0)</li>
</ul>
Ruby master - Feature #13303 (Feedback): String#any? as !String#empty?
https://redmine.ruby-lang.org/issues/13303
2017-03-12T18:29:26Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Once I proposed "some container#nonempty?" on <a class="issue tracker-2 status-7 priority-4 priority-default closed" title="Feature: some container#nonempty? (Feedback)" href="https://redmine.ruby-lang.org/issues/12075">#12075</a>, and understand there's Array#any?.</p>
<p>Today I found String doesn't have such method.</p>
Ruby master - Misc #13027 (Closed): Release Engineering 2.4
https://redmine.ruby-lang.org/issues/13027
2016-12-12T14:43:37Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>META ticket for Release Engineering 2.4.</p>
<p>see also <a class="version" href="https://redmine.ruby-lang.org/versions/33">2.4</a></p>
<ul>
<li>current status: feature freeze</li>
<li>Q: Can I add a new feature?
<ul>
<li>A: No. Its status is already "feature freeze".</li>
</ul>
</li>
<li>Q: Can I fix a bug?
<ul>
<li>A: Yes</li>
</ul>
</li>
<li>Q: I want to complain about 2.4.0-rc1
<ul>
<li>A: create a ticket. It may change 2.4.0 RTM.</li>
</ul>
</li>
<li>Q: When ruby_2_4 branch is created?
<ul>
<li>A: scheduled on 2016-12-23</li>
</ul>
</li>
<li>Q: When Ruby 2.4.0 is released?
<ul>
<li>A: scheduled at 2016-12-25T00:00:00/03:00:00</li>
</ul>
</li>
</ul>
Ruby master - Bug #12923 (Closed): Accessing singleton_class of fstring cause assertion failure
https://redmine.ruby-lang.org/issues/12923
2016-11-11T17:57:23Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>以下のワンライナーが「Assertion Failed: string.c:343:register_fstring:RBASIC_CLASS(ret) == rb_cString」します。</p>
<p>./miniruby -e'#encoding:us-ascii' -e'ObjectSpace.each_object{|o| o.singleton_class if o.is_a?(String)}; "hoge".intern'</p>
<p>クラッシュログは自分で走らせてもらうとして、何が起きているかというと、<br>
(1) 文字列リテラルをはじめとして、何らかのかたちでシンボルを作らずにrb_fstringからfrozenなStringを作る<br>
(2) その文字列に対してsingleton_classを呼ぶ。するとそのRVALUE->klassにsingleton_classが代入される<br>
(3) 同じ内容の文字列でString#internする(1.でシンボルを作っているとlookup_str_sym()にひっかかる)<br>
(4) register_fstringの"assert(RBASIC_CLASS(ret) == rb_cString);"で落ちる</p>
<p>しかし、どう直しましょうかね。</p>
Ruby master - Misc #12283 (Closed): Obsolete ChangeLog and commit message in Git-style
https://redmine.ruby-lang.org/issues/12283
2016-04-14T18:57:41Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>How about Git-style commit message instead of ChangeLog?</p>
<a name="Proposal"></a>
<h2 >Proposal<a href="#Proposal" class="wiki-anchor">¶</a></h2>
<p>After we reach the consensus</p>
<ol>
<li>Write a commit message in Git-style.</li>
</ol>
<ul>
<li>Line 1: summary of commit (around 80 characters or less, <50 is better)</li>
<li>Line 2: empty line</li>
<li>Line 3-: More detailed explanation of commit</li>
</ul>
<p>See also: <a href="https://git-scm.com/book/ch5-2.html#Commit-Guidelines" class="external">https://git-scm.com/book/ch5-2.html#Commit-Guidelines</a></p>
<ol start="2">
<li>Stop manually edit ChangeLog and auto-generate on <code>make dist</code>.</li>
</ol>
<a name="Rationale"></a>
<h2 >Rationale<a href="#Rationale" class="wiki-anchor">¶</a></h2>
<p>A good commit message should include the objective of the commit.<br>
Committers should write "what purpose the change is for".<br>
In this sense, ChangeLog is not a good format. It lists per-file changes, so committers tend to write just "how the files were changed".</p>
<p>Also, ChangeLog causes commit conflicts frequently.<br>
Though it is not related with the actual commit.<br>
People who uses svn/git should see the log with it; ChangeLog is only for tarball users.</p>
<a name="Status"></a>
<h2 >Status<a href="#Status" class="wiki-anchor">¶</a></h2>
<p>mame made this proposal at the developers' meeting (13 Apr.), and there was no objection.</p>
<p>Matz agreed with this proposal, provided that a ChangeLog-like plain-text file is generated from the commit log.<br>
The release manager will create the file when Ruby is released.</p>
<a name="Note"></a>
<h3 >Note<a href="#Note" class="wiki-anchor">¶</a></h3>
<p>This ticket does NOT propose a migration from SVN to Git. Never discuss that in this ticket.</p>
Ruby master - Feature #12244 (Open): Add a way to `integer - integer % num`
https://redmine.ruby-lang.org/issues/12244
2016-04-02T13:45:33Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>We sometimes calculates <code>integer - integer % num</code>.</p>
<p>For example time series events into time partitions, we write code like</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">event</span> <span class="c1"># {time: 1459580435, name: "hoge", text: "Rawr!"}</span>
<span class="n">partition</span> <span class="o">=</span> <span class="n">event</span><span class="p">[</span><span class="ss">:time</span><span class="p">]</span> <span class="o">-</span> <span class="n">event</span><span class="p">[</span><span class="ss">:time</span><span class="p">]</span> <span class="o">%</span> <span class="n">num</span>
<span class="n">chunk</span> <span class="o">=</span> <span class="n">get_chunk</span><span class="p">(</span><span class="n">partition</span><span class="p">)</span>
<span class="n">chunk</span><span class="p">.</span><span class="nf">write</span> <span class="n">event</span>
</code></pre>
<p><a href="https://twitter.com/tagomoris/status/715814050534461440" class="external">https://twitter.com/tagomoris/status/715814050534461440</a><br>
<a href="https://twitter.com/tagomoris/status/715814961260457985" class="external">https://twitter.com/tagomoris/status/715814961260457985</a></p>
<p>The name is always issue.<br>
There are some suggestions likes Integer#adjust](<a href="https://twitter.com/cocoatomo/status/716088708655489024" class="external">https://twitter.com/cocoatomo/status/716088708655489024</a>).</p>
<p>kosaki says <a href="https://twitter.com/kosaki55tea/status/716059296186765312" class="external">Excel's FLOOR() function is FLOOR(number, significance)</a>.<br>
Therefore Ruby should be <a href="https://twitter.com/kosaki55tea/status/716106530114768897" class="external">Integer#floor(digits=1, significance: nil)</a>.<br>
<a href="https://twitter.com/kosaki55tea/status/716107516409581568" class="external">kosaki agrees this</a>.</p>
<p>I checked the speed of a half baked implementation..., but it's 10x slow...</p>
<pre><code>% time ./miniruby -e'i=10000000;while i>0;i-=1;1459497599.floor(significance: 3600);end'
./miniruby 6.58s user 0.02s system 99% cpu 6.596 total
#3 1459604131 22:35:31 naruse@windy:~/obj/ruby
% time ./miniruby -e'i=10000000;while i>0;i-=1;t=1459497599;t-t%3600;end'
./miniruby -e'i=10000000;while i>0;i-=1;t=1459497599;t-t%3600;end' 0.52s user 0.00s system 99% cpu 0.520 total
</code></pre>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/numeric.c b/numeric.c
index 37217a1..f6acfe3 100644
</span><span class="gd">--- a/numeric.c
</span><span class="gi">+++ b/numeric.c
</span><span class="p">@@ -4123,6 +4123,42 @@</span> int_dotimes(VALUE num)
<span class="err">
</span> /*
* call-seq:
<span class="gi">+ * int.floor([ndigits]) -> integer or float
+ *
+ * Rounds +int+ to a given precision in decimal digits (default 0 digits).
+ *
+ * Precision may be negative. Returns a floating point number when +ndigits+
+ * is positive, +self+ for zero, and round down for negative.
+ *
+ * 1.round #=> 1
+ * 1.round(2) #=> 1.0
+ * 15.round(-1) #=> 20
+ */
+
+static VALUE
+int_floor(int argc, VALUE* argv, VALUE num)
+{
+ static ID keyword_ids[1];
+ VALUE kwargs[1], ndigits, opt;
+ if (!keyword_ids[0]) {
+ CONST_ID(keyword_ids[0], "significance");
+ }
+
+ rb_scan_args(argc, argv, "01:", &ndigits, &opt);
+ if (!NIL_P(opt)) {
+ VALUE factor;
+ long a, b;
+ rb_get_kwargs(opt, keyword_ids, 0, 1, kwargs);
+ factor = kwargs[0];
+ a = FIX2LONG(num);
+ b = FIX2LONG(factor);
+ return LONG2FIX(a - a % b);
+ }
+ return Qnil;
+}
+
+/*
+ * call-seq:
</span> * int.round([ndigits]) -> integer or float
*
* Rounds +int+ to a given precision in decimal digits (default 0 digits).
<span class="p">@@ -4321,7 +4357,7 @@</span> Init_Numeric(void)
rb_define_method(rb_cInteger, "to_i", int_to_i, 0);
rb_define_method(rb_cInteger, "to_int", int_to_i, 0);
rb_define_method(rb_cInteger, "to_f", int_to_f, 0);
<span class="gd">- rb_define_method(rb_cInteger, "floor", int_to_i, 0);
</span><span class="gi">+ rb_define_method(rb_cInteger, "floor", int_floor, -1);
</span> rb_define_method(rb_cInteger, "ceil", int_to_i, 0);
rb_define_method(rb_cInteger, "truncate", int_to_i, 0);
rb_define_method(rb_cInteger, "round", int_round, -1);
</code></pre>
Ruby master - Feature #12208 (Closed): Improve ri command
https://redmine.ruby-lang.org/issues/12208
2016-03-23T05:22:46Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Ruby has well documented in rdoc.<br>
It also has a frontend CLI.</p>
<p>But people seems not using <code>ri</code>...</p>
<p>At first, write your request here to improve ri command!</p>
Ruby master - Feature #12075 (Feedback): some container#nonempty?
https://redmine.ruby-lang.org/issues/12075
2016-02-16T08:08:28Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>I sometimes write following code.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">ary</span> <span class="o">=</span> <span class="n">some_metho_returns_nil_or_empty_container</span><span class="p">()</span> <span class="c1"># nil or "" or [] or {}</span>
<span class="k">if</span> <span class="n">ary</span> <span class="o">&&</span> <span class="o">!</span><span class="n">ary</span><span class="p">.</span><span class="nf">empty?</span>
<span class="c1"># some code</span>
<span class="k">end</span>
</code></pre>
<p>But the condition <code>ary && !ary.empty?</code> is too long and complex.<br>
Though Ruby 2.3 introduces <code>&.</code>, but this can’t be written as <code>ary&.empty?</code>.</p>
<p>One idea is add <code>nonempty?</code> write as <code>ary&.nonempty?</code>.</p>
<p>akr: <code>nonempty?</code> is not good name because human is not good at handling</p>
<p>This discussion matches following core classes:</p>
<ul>
<li>String</li>
<li>Array</li>
<li>Hash</li>
</ul>
Ruby master - Feature #12010 (Closed): Exclude dot and dotdot from Dir#each
https://redmine.ruby-lang.org/issues/12010
2016-01-20T02:17:16Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p><code>Dir#each</code> and <code>Dir#read</code> (including <code>Dir.entries</code>, <code>Dir.foreach</code> and other methods) return <code>"."</code> and <code>".."</code> at first.<br>
But through the all real use case <code>"."</code> and <code>".."</code> are useless.<br>
How about excluding them?</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/dir.c b/dir.c
index 193b5be..4c23a2d 100644
</span><span class="gd">--- a/dir.c
</span><span class="gi">+++ b/dir.c
</span><span class="p">@@ -699,6 +699,8 @@</span> fundamental_encoding_p(rb_encoding *enc)
#else
# define READDIR(dir, enc) readdir((dir))
#endif
<span class="gi">+#define DIR_IS_DOT_OR_DOTDOT(dp) ((dp)->d_name[0] == '.' && \
+ ((dp)->d_name[1] == '\0' || ((dp)->d_name[1] == '.' && (dp)->d_name[2] == '\0')))
</span>
/*
* call-seq:
<span class="p">@@ -720,13 +722,12 @@</span> dir_read(VALUE dir)
GetDIR(dir, dirp);
errno = 0;
<span class="gd">- if ((dp = READDIR(dirp->dir, dirp->enc)) != NULL) {
- return rb_external_str_new_with_enc(dp->d_name, NAMLEN(dp), dirp->enc);
- }
- else {
- if (errno != 0) rb_sys_fail(0);
- return Qnil; /* end of stream */
</span><span class="gi">+ while ((dp = READDIR(dirp->dir, dirp->enc)) != NULL) {
+ if (!DIR_IS_DOT_OR_DOTDOT(dp))
+ return rb_external_str_new_with_enc(dp->d_name, NAMLEN(dp), dirp->enc);
</span> }
<span class="gi">+ if (errno != 0) rb_sys_fail(0);
+ return Qnil; /* end of stream */
</span> }
/*
<span class="p">@@ -764,6 +765,7 @@</span> dir_each(VALUE dir)
const char *name = dp->d_name;
size_t namlen = NAMLEN(dp);
VALUE path;
<span class="gi">+ if (DIR_IS_DOT_OR_DOTDOT(dp)) continue;
</span> #if NORMALIZE_UTF8PATH
if (norm_p && has_nonascii(name, namlen) &&
!NIL_P(path = rb_str_normalize_ospath(name, namlen))) {
<span class="gh">diff --git a/test/pathname/test_pathname.rb b/test/pathname/test_pathname.rb
index 2690a3f..33f0d44 100644
</span><span class="gd">--- a/test/pathname/test_pathname.rb
</span><span class="gi">+++ b/test/pathname/test_pathname.rb
</span><span class="p">@@ -1238,7 +1238,7 @@</span> def test_entries
with_tmpchdir('rubytest-pathname') {|dir|
open("a", "w") {}
open("b", "w") {}
<span class="gd">- assert_equal([Pathname("."), Pathname(".."), Pathname("a"), Pathname("b")], Pathname(".").entries.sort)
</span><span class="gi">+ assert_equal([Pathname("a"), Pathname("b")], Pathname(".").entries.sort)
</span> }
end
<span class="p">@@ -1248,7 +1248,7 @@</span> def test_each_entry
open("b", "w") {}
a = []
Pathname(".").each_entry {|v| a << v }
<span class="gd">- assert_equal([Pathname("."), Pathname(".."), Pathname("a"), Pathname("b")], a.sort)
</span><span class="gi">+ assert_equal([Pathname("a"), Pathname("b")], a.sort)
</span> }
end
<span class="p">@@ -1278,7 +1278,7 @@</span> def test_opendir
Pathname(".").opendir {|d|
d.each {|e| a << e }
}
<span class="gd">- assert_equal([".", "..", "a", "b"], a.sort)
</span><span class="gi">+ assert_equal(["a", "b"], a.sort)
</span> }
end
<span class="gh">diff --git a/test/ruby/test_dir.rb b/test/ruby/test_dir.rb
index 0cc5a6a..d3f6602 100644
</span><span class="gd">--- a/test/ruby/test_dir.rb
</span><span class="gi">+++ b/test/ruby/test_dir.rb
</span><span class="p">@@ -186,7 +186,7 @@</span> def test_glob_recursive
def assert_entries(entries)
entries.sort!
<span class="gd">- assert_equal(%w(. ..) + ("a".."z").to_a, entries)
</span><span class="gi">+ assert_equal(("a".."z").to_a, entries)
</span> end
def test_entries
</code></pre>
Ruby master - Feature #12005 (Closed): Unify Fixnum and Bignum into Integer
https://redmine.ruby-lang.org/issues/12005
2016-01-19T02:38:01Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>CRuby has two <code>Integer</code> classes, <code>Fixnum</code> and <code>Bignum</code>.<br>
But it is implementation detail.<br>
They should be seen as a single class <code>Integer</code> like <code>Flonum</code>.</p>
<a name="Compatibility-note"></a>
<h2 >Compatibility note<a href="#Compatibility-note" class="wiki-anchor">¶</a></h2>
<ul>
<li>Q: How do I check whether Fixnum and Bignum are unified or not?</li>
<li>A: check RUBY_INTEGER_UNIFICATION macro</li>
</ul>
Ruby master - Feature #11801 (Closed): rb_inspect shouldn't raise error even if calling inspect r...
https://redmine.ruby-lang.org/issues/11801
2015-12-10T04:22:06Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Current rb_inspect raises Encoding::Compatibility error if obj.inspect returns a string<br>
whose encoding is not compatible with resulted string's encoding.<br>
But the behavior is not useful on inspecting an array or a hash containing such strings<br>
because it prevents to dump them.</p>
<p>Following patch changes to escape such strings like String#inspect.</p>
<pre><code>diff --git a/object.c b/object.c
index d339ff9..1f73cb4 100644
--- a/object.c
+++ b/object.c
@@ -465,6 +465,7 @@ rb_any_to_s(VALUE obj)
return str;
}
+VALUE rb_str_escape(VALUE str);
/*
* If the default external encoding is ASCII compatible, the encoding of
* the inspected result must be compatible with it.
@@ -478,11 +479,11 @@ rb_inspect(VALUE obj)
rb_encoding *ext = rb_default_external_encoding();
if (!rb_enc_asciicompat(ext)) {
if (!rb_enc_str_asciionly_p(str))
- rb_raise(rb_eEncCompatError, "inspected result must be ASCII only if default external encoding is ASCII incompatible");
+ return rb_str_escape(str);
return str;
}
if (rb_enc_get(str) != ext && !rb_enc_str_asciionly_p(str))
- rb_raise(rb_eEncCompatError, "inspected result must be ASCII only or use the default external encoding");
+ return rb_str_escape(str);
return str;
}
diff --git a/string.c b/string.c
index e6df91d..319c516 100644
--- a/string.c
+++ b/string.c
@@ -5265,6 +5265,70 @@ rb_str_buf_cat_escaped_char(VALUE result, unsigned int c, int unicode_p)
return l;
}
+VALUE
+rb_str_escape(VALUE str)
+{
+ int encidx = ENCODING_GET(str);
+ rb_encoding *enc = rb_enc_from_index(encidx);
+ const char *p = RSTRING_PTR(str);
+ const char *pend = RSTRING_END(str);
+ const char *prev = p;
+ char buf[CHAR_ESC_LEN + 1];
+ VALUE result = rb_str_buf_new(0);
+ int unicode_p = rb_enc_unicode_p(enc);
+ int asciicompat = rb_enc_asciicompat(enc);
+
+ while (p < pend) {
+ unsigned int c, cc;
+ int n = rb_enc_precise_mbclen(p, pend, enc);
+ if (!MBCLEN_CHARFOUND_P(n)) {
+ if (p > prev) str_buf_cat(result, prev, p - prev);
+ n = rb_enc_mbminlen(enc);
+ if (pend < p + n)
+ n = (int)(pend - p);
+ while (n--) {
+ snprintf(buf, CHAR_ESC_LEN, "\\x%02X", *p & 0377);
+ str_buf_cat(result, buf, strlen(buf));
+ prev = ++p;
+ }
+ continue;
+ }
+ n = MBCLEN_CHARFOUND_LEN(n);
+ c = rb_enc_mbc_to_codepoint(p, pend, enc);
+ p += n;
+ switch (c) {
+ case '\n': cc = 'n'; break;
+ case '\r': cc = 'r'; break;
+ case '\t': cc = 't'; break;
+ case '\f': cc = 'f'; break;
+ case '\013': cc = 'v'; break;
+ case '\010': cc = 'b'; break;
+ case '\007': cc = 'a'; break;
+ case 033: cc = 'e'; break;
+ default: cc = 0; break;
+ }
+ if (cc) {
+ if (p - n > prev) str_buf_cat(result, prev, p - n - prev);
+ buf[0] = '\\';
+ buf[1] = (char)cc;
+ str_buf_cat(result, buf, 2);
+ prev = p;
+ }
+ else if (asciicompat && rb_enc_isascii(c, enc) && ISPRINT(c)) {
+ }
+ else {
+ if (p - n > prev) str_buf_cat(result, prev, p - n - prev);
+ rb_str_buf_cat_escaped_char(result, c, unicode_p);
+ prev = p;
+ }
+ }
+ if (p > prev) str_buf_cat(result, prev, p - prev);
+ ENCODING_CODERANGE_SET(result, rb_usascii_encindex(), ENC_CODERANGE_7BIT);
+
+ OBJ_INFECT_RAW(result, str);
+ return result;
+}
+
/*
* call-seq:
* str.inspect -> string
diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb
index ca25f85..2e9e65b 100644
--- a/test/ruby/test_m17n.rb
+++ b/test/ruby/test_m17n.rb
@@ -278,7 +278,7 @@ def test_object_utf16_32_inspect
o = Object.new
[Encoding::UTF_16BE, Encoding::UTF_16LE, Encoding::UTF_32BE, Encoding::UTF_32LE].each do |e|
o.instance_eval "undef inspect;def inspect;'abc'.encode('#{e}');end"
- assert_raise(Encoding::CompatibilityError) { [o].inspect }
+ assert_equal '[abc]', [o].inspect
end
ensure
Encoding.default_internal = orig_int
@@ -302,13 +302,18 @@ def o.inspect
def o.inspect
"abc".encode(Encoding.default_external)
end
- assert_raise(Encoding::CompatibilityError) { [o].inspect }
+ assert_equal '[abc]', [o].inspect
Encoding.default_external = Encoding::US_ASCII
def o.inspect
"\u3042"
end
- assert_raise(Encoding::CompatibilityError) { [o].inspect }
+ assert_equal '[\u3042]', [o].inspect
+
+ def o.inspect
+ "\x82\xa0".force_encoding(Encoding::Windows_31J)
+ end
+ assert_equal '[\x{82A0}]', [o].inspect
ensure
Encoding.default_internal = orig_int
Encoding.default_external = orig_ext
diff --git a/core/array/shared/inspect.rb b/core/array/shared/inspect.rb
index dc30518..a169fd0 100644
--- a/core/array/shared/inspect.rb
+++ b/core/array/shared/inspect.rb
@@ -83,9 +83,9 @@ describe :array_inspect, shared: true do
it "raises if inspected result is not default external encoding" do
utf_16be = mock("utf_16be")
- utf_16be.should_receive(:inspect).and_return("utf_16be".encode!(Encoding::UTF_16BE))
+ utf_16be.should_receive(:inspect).and_return(%<"utf_16be \u3042">.encode!(Encoding::UTF_16BE))
- lambda { [utf_16be].send(@method) }.should raise_error(Encoding::CompatibilityError)
+ [utf_16be].send(@method).should == '["utf_16be \u3042"]'
end
end
end
</code></pre>
Ruby master - Bug #11669 (Closed): inconsitent behavior of refining frozen class
https://redmine.ruby-lang.org/issues/11669
2015-11-09T05:38:34Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Is this expected behavior?</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">C</span>
<span class="k">def</span> <span class="nf">foo</span>
<span class="nb">p</span> <span class="mi">1</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">Foo</span>
<span class="n">refine</span> <span class="no">C</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">foo</span>
<span class="nb">p</span> <span class="mi">2</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">using</span> <span class="no">Foo</span>
<span class="no">C</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">foo</span> <span class="c1">#=> 2</span>
<span class="no">C</span><span class="p">.</span><span class="nf">freeze</span>
<span class="k">module</span> <span class="nn">Foo</span>
<span class="n">refine</span> <span class="no">C</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">foo</span>
<span class="nb">p</span> <span class="mi">3</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">bar</span> <span class="c1">#=> can't modify frozen class (RuntimeError)</span>
<span class="nb">p</span> <span class="mi">3</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">C</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">foo</span>
<span class="no">C</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">bar</span>
</code></pre>
<pre><code>ruby 2.3.0dev (2015-10-26 trunk 52291) [x86_64-darwin15]
2
test.rb:21:in `block in <module:Foo>': can't modify frozen class (RuntimeError)
from test.rb:17:in `refine'
from test.rb:17:in `<module:Foo>'
from test.rb:16:in `<main>'
</code></pre>
Ruby master - Misc #11516 (Closed): Ruby 2.3.0 release engeneering
https://redmine.ruby-lang.org/issues/11516
2015-09-09T06:13:18Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>For the management of release blockers.</p>
<p>Current Phase:<br>
Next release: preview1</p>
<p>Q: When ruby_2_2 branch is created?<br>
A: On RC1</p>
Ruby master - Misc #11474 (Closed): [META] Call for Feature Proposals for Ruby 2.3
https://redmine.ruby-lang.org/issues/11474
2015-08-21T05:44:04Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>This is meta ticket for Call for Feature Proposals for Ruby 2.3.<br>
After you attach your slide to the related ticket, write ticket number as a comment here to avoid I miss it.</p>
Ruby master - Feature #11302 (Closed): Dir.entries and Dir.foreach without [".", ".."]
https://redmine.ruby-lang.org/issues/11302
2015-06-24T06:24:58Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Dir.entries returns an array of its content with "." and "..".<br>
But as far as I met, almost all cases don't need them.</p>
<p>How about adding such new method or options?</p>
Ruby master - Feature #11253 (Closed): rb_io_modestr_oflags for Ruby API
https://redmine.ruby-lang.org/issues/11253
2015-06-12T08:18:12Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>If you have a wrapper of IO.open, you may handle mode.<br>
For example on Windows, you may want to add 'b' / OBINARY to given mode.</p>
<p>But some modes has only integer form like O_CLOEXEC, O_EXCL.<br>
If so you need to convert from modestr to oflags</p>
<p>Therefore how about adding a Ruby API version of rb_io_modestr_oflags</p>
Ruby master - Misc #10553 (Closed): Ruby 2.2.0 release engeneering
https://redmine.ruby-lang.org/issues/10553
2014-11-28T13:01:41Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>For the management of release blockers.</p>
<p>Current Phase: feature freeze; changing feature is not allowed unless naruse explicitly allowed.<br>
Next release: RC1 (scheduled on 2014-12-1x)</p>
<p>Q: When ruby_2_2 branch is created?<br>
A: On RC1</p>
<p>Q: Can I add/change a feature?<br>
A: Get explicit permission from naruse</p>
Ruby master - Bug #10397 (Closed): gcc 4.1.2 for x86 can't build trunk
https://redmine.ruby-lang.org/issues/10397
2014-10-19T07:12:15Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Recently CentOS 5.6 x86 can't build ruby-trunk.<br>
This is since r47562 and it hit <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=16185" class="external">gcc bug</a>.</p>
<p>Do people want CRuby to continue RHEL/CentOS 5.6 support?<br>
If so, ideally it is fixed by gcc.</p>
Ruby master - Feature #9816 (Assigned): 文字列内の数字を数値として比較するメソッド
https://redmine.ruby-lang.org/issues/9816
2014-05-08T09:37:26Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>文字列内の数字を数値として比較するメソッドを追加しませんか</p>
<p>そのような比較は一般的な用途としてはGUIシェルのファイラーが比較に用いており、<br>
Windows では StrCmpLogicalW が、OS X では NSString:compare:options:へのNSNumericSearch定数が提供されています。<br>
<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb759947(v=vs.85).aspx" class="external">http://msdn.microsoft.com/en-us/library/windows/desktop/bb759947(v=vs.85).aspx</a><br>
<a href="https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/c/econst/NSNumericSearch" class="external">https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/c/econst/NSNumericSearch</a></p>
<p>上記のような処理自体はさほど難しいものではありませんが、Rubyレベルで実装すると大量のオブジェクトを作ってしまいます。<br>
例えば <code>Gem::Version.new("2.1.10".freeze)<=>Gem::Version.new("2.1.9".freeze)</code> は47個、<br>
<code>"2.1.10".freeze.split('.').map(&:to_i)<=>"2.1.9".freeze.split('.').map(&:to_i)</code> だと16個のオブジェクトを作ります。<br>
<code>"2.1.10".freeze.numericcmp"2.1.9".freeze</code> ならば、もちろんオブジェクトは一つも作りません。</p>
<p>なお、上記の例でも示唆していますが、本メソッドは Ruby のバージョン表記の TEENY が2桁になった場合の比較に用いることができます。</p>
<p>パッチは以下の通りです。<br>
なお、メソッド名は String#numericcmp としています。<br>
(String#casecmpを念頭に置いた)</p>
<pre><code>diff --git a/string.c b/string.c
index c589c80..66f667f 100644
--- a/string.c
+++ b/string.c
@@ -2569,6 +2569,131 @@ rb_str_casecmp(VALUE str1, VALUE str2)
return INT2FIX(-1);
}
+VALUE
+numerical_compare(const char **pp1, const char *p1end, const char **pp2, const char *p2end)
+{
+ const char *s1 = *pp1, *p1, *s2 = *pp2, *p2;
+ ptrdiff_t len1, len2;
+ int r;
+
+ while (s1 < p1end && *s1 == '0') s1++;
+ p1 = s1;
+ while (p1 < p1end && ISDIGIT(*p1)) p1++;
+ len1 = p1 - s1;
+
+ while (s2 < p2end && *s2 == '0') s2++;
+ p2 = s2;
+ while (p2 < p2end && ISDIGIT(*p2)) p2++;
+ len2 = p2 - s2;
+
+ if (len1 != len2) {
+ return INT2FIX(len1 < len2 ? -1 : 1);
+ }
+
+ r = memcmp(s1, s2, len1);
+ if (r) return r < 0 ? INT2FIX(-1) : INT2FIX(1);
+
+ len1 = s1 - *pp1;
+ len2 = s2 - *pp2;
+ if (len1 != len2) {
+ return INT2FIX(len1 < len2 ? -1 : 1);
+ }
+
+ *pp1 = p1;
+ *pp2 = p2;
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * str.numericcmp(other_str) -> -1, 0, +1 or nil
+ *
+ * Variant of <code>String#<=></code>, which considers digits in strings
+ * are numeric value..
+ *
+ * "a1".numericcmp("a1") #=> 0
+ * "aa".numericcmp("a1") #=> 1
+ * "a1".numericcmp("aa") #=> -1
+ * "a1".numericcmp("a01") #=> -1
+ * "2.1.2".numericcmp("2.1.10") #=> 1
+ */
+
+static VALUE
+rb_str_numericcmp(VALUE str1, VALUE str2)
+{
+ long len;
+ rb_encoding *enc;
+ const char *p1, *p1end, *p2, *p2end;
+
+ StringValue(str2);
+ enc = rb_enc_compatible(str1, str2);
+ if (!enc) {
+ return Qnil;
+ }
+
+ p1 = RSTRING_PTR(str1); p1end = RSTRING_END(str1);
+ p2 = RSTRING_PTR(str2); p2end = RSTRING_END(str2);
+ if (single_byte_optimizable(str1) && single_byte_optimizable(str2)) {
+ while (p1 < p1end && p2 < p2end) {
+ if (ISDIGIT(*p1)) {
+ if (ISDIGIT(*p2)) {
+ VALUE r = numerical_compare(&p1, p1end, &p2, p2end);
+ if (!NIL_P(r)) return r;
+ }
+ else {
+ return INT2FIX(-1);
+ }
+ }
+ else if (ISDIGIT(*p2)) {
+ return INT2FIX(1);
+ }
+ if (*p1 != *p2) return INT2FIX(*p1 < *p2 ? -1 : 1);
+ p1++;
+ p2++;
+ }
+ }
+ else {
+ while (p1 < p1end && p2 < p2end) {
+ int l1, c1 = rb_enc_ascget(p1, p1end, &l1, enc);
+ int l2, c2 = rb_enc_ascget(p2, p2end, &l2, enc);
+
+ if (0 <= c1 && 0 <= c2) {
+ if (ISDIGIT(*p1)) {
+ if (ISDIGIT(*p2)) {
+ VALUE r = numerical_compare(&p1, p1end, &p2, p2end);
+ if (!NIL_P(r)) return r;
+ }
+ else {
+ return INT2FIX(-1);
+ }
+ }
+ else if (ISDIGIT(*p2)) {
+ return INT2FIX(1);
+ }
+ if (*p1 != *p2) return INT2FIX(*p1 < *p2 ? -1 : 1);
+ p1++;
+ p2++;
+ }
+ else {
+ int r;
+ l1 = rb_enc_mbclen(p1, p1end, enc);
+ l2 = rb_enc_mbclen(p2, p2end, enc);
+ len = l1 < l2 ? l1 : l2;
+ r = memcmp(p1, p2, len);
+ if (r != 0)
+ return INT2FIX(r < 0 ? -1 : 1);
+ if (l1 != l2)
+ return INT2FIX(l1 < l2 ? -1 : 1);
+ }
+ p1 += l1;
+ p2 += l2;
+ }
+ }
+ if (RSTRING_LEN(str1) == RSTRING_LEN(str2)) return INT2FIX(0);
+ if (RSTRING_LEN(str1) > RSTRING_LEN(str2)) return INT2FIX(1);
+ return INT2FIX(-1);
+}
+
static long
rb_str_index(VALUE str, VALUE sub, long offset)
{
@@ -8721,6 +8846,7 @@ Init_String(void)
rb_define_method(rb_cString, "eql?", rb_str_eql, 1);
rb_define_method(rb_cString, "hash", rb_str_hash_m, 0);
rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1);
+ rb_define_method(rb_cString, "numericcmp", rb_str_numericcmp, 1);
rb_define_method(rb_cString, "+", rb_str_plus, 1);
rb_define_method(rb_cString, "*", rb_str_times, 1);
rb_define_method(rb_cString, "%", rb_str_format_m, 1);
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index 8366424..f9c788b 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -2104,6 +2104,29 @@ class TestString < Test::Unit::TestCase
assert_equal(1, "\u3042B".casecmp("\u3042a"))
end
+ def test_numericcmp
+ assert_equal(-1, "2.1.0".numericcmp("2.1.1"))
+ assert_equal(-1, "2.1.9".numericcmp("2.1.10"))
+ assert_equal( 0, "a1".numericcmp("a1"))
+ assert_equal( 1, "aa".numericcmp("a1"))
+ assert_equal(-1, "a1".numericcmp("aa"))
+ assert_equal(-1, "a1".numericcmp("a01"))
+ assert_equal(-1, "a0001".numericcmp("a00001"))
+ assert_equal( 0, "a1a".numericcmp("a1a"))
+ assert_equal( 1, "a1b".numericcmp("a1a"))
+ assert_equal(-1, "a9a".numericcmp("a10a"))
+ assert_equal( 1, "b".numericcmp("a"))
+ assert_equal( 0, "\u30421".numericcmp("\u30421"))
+ assert_equal( 1, "\u3042\u3042".numericcmp("\u30421"))
+ assert_equal(-1, "\u30421".numericcmp("\u3042\u3042"))
+ assert_equal(-1, "\u30421".numericcmp("\u304201"))
+ assert_equal(-1, "\u30420001".numericcmp("\u304200001"))
+ assert_equal( 0, "\u30421\u3042".numericcmp("\u30421\u3042"))
+ assert_equal( 1, "\u30421\u3044".numericcmp("\u30421\u3042"))
+ assert_equal(-1, "\u30429\u3042".numericcmp("\u304210\u3042"))
+ assert_equal( 1, "\u3044".numericcmp("\u3042"))
+ end
+
def test_upcase2
assert_equal("\u3042AB", "\u3042aB".upcase)
end
</code></pre>
Ruby master - Feature #9772 (Rejected): IO#statfs and File::Statfs
https://redmine.ruby-lang.org/issues/9772
2014-04-24T04:03:50Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>IO#statfs and File::Statfs を追加しませんか。<br>
(テストで statfs.f_type が必要だったのでとりあえず追加してしまっていますが)</p>
<p>statfs(2) は Unix 系 OS でそこそこ普及している、あるパスが属するファイルシステムについての情報を得るためのシステムコールです。<br>
OS によって多少差がありますが、だいたい以下の様な情報が得られます。</p>
<pre><code> struct statfs {
uint32_t f_type; /* type of filesystem */
uint64_t f_bsize; /* filesystem fragment size */
uint64_t f_blocks; /* total data blocks in filesystem */
uint64_t f_bfree; /* free blocks in filesystem */
int64_t f_bavail; /* free blocks avail to non-superuser */
uint64_t f_files; /* total file nodes in filesystem */
int64_t f_ffree; /* free nodes avail to non-superuser */
char f_fstypename[MFSNAMELEN]; /* filesystem type name */
};
</code></pre>
<p>f_type の値が OS 依存だったり、Linux 以外だとそもそもどれがどの値かきちんと定義されていないとか<br>
ツッコミどころの多い API ではあるのですが、他では得られない情報が得られます。</p>
<p>たとえば、以前から CRuby で使われている用途としては、あるファイルの乗っているファイルシステムが、<br>
HFS+ かどうかがわかります。言い換えると、ファイル名が正規化されているかどうかがわかります。<br>
ありがちな反論として、書き込めば正規化されるかわかるだろうというのがありえますが、<br>
目当てのファイルと同じディレクトリに書き込めるとは限りません。<br>
違うディレクトリだと別のファイルシステムがマウントされている可能性があります。</p>
<p>なお今回の用途は、SEEK_DATA/SEEK_HOLEができるか否かを、実際にやってみる以外の方法で知りたかった、というものです。<br>
(Rubyのテストなのにやってみて調べるではテストにあまりならない)</p>
Ruby master - Feature #9647 (Closed): File::Stat#birthtimeの追加
https://redmine.ruby-lang.org/issues/9647
2014-03-17T05:13:51Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>File::Stat#birthtimeを追加しませんか。</p>
<p>以下の様なシステムの stat(2) には st_birthtimespec があり、<br>
(ctime = change time ではなく) ファイルを作成した日時を得ることができます。<br>
<a href="http://netbsd.gw.com/cgi-bin/man-cgi?stat+2+NetBSD-current" class="external">http://netbsd.gw.com/cgi-bin/man-cgi?stat+2+NetBSD-current</a><br>
<a href="http://www.freebsd.org/cgi/man.cgi?query=stat&sektion=2&apropos=0&manpath=FreeBSD+10.0-RELEASE" class="external">http://www.freebsd.org/cgi/man.cgi?query=stat&sektion=2&apropos=0&manpath=FreeBSD+10.0-RELEASE</a><br>
<a href="https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/stat.2.html" class="external">https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/stat.2.html</a></p>
<p>また、Windowsはbirthtimeがあるがctimeがないという環境ですので、birthtimeはctimeを返します。<br>
<a href="http://msdn.microsoft.com/ja-jp/library/ms350241(v=vs.71).aspx" class="external">http://msdn.microsoft.com/ja-jp/library/ms350241(v=vs.71).aspx</a></p>
<p>今回のパッチではLinuxやOpenBSDなど、struct statにbirthtimeがない環境では、<br>
Windows同様ctimeを返すようにしています。<br>
(が、意味が違うからWindows以外ではNotImpErrorの方がいいかも)</p>
<p><a href="https://github.com/nurse/ruby/compare/ruby:trunk...birthtime" class="external">https://github.com/nurse/ruby/compare/ruby:trunk...birthtime</a></p>
Ruby master - Bug #9287 (Closed): 'rb_obj_write' discards qualifiers from pointer target type
https://redmine.ruby-lang.org/issues/9287
2013-12-23T18:22:00Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>array.c: In function 'rb_ary_new_from_args':<br>
array.c:506: warning: passing argument 2 of 'rb_obj_write' discards qualifiers from pointer target type<br>
などといった警告が出ます。</p>
<p><a href="http://fb32.rubyci.org/~chkbuild/ruby-trunk/log/20131223T070301Z.log.html.gz" class="external">http://fb32.rubyci.org/~chkbuild/ruby-trunk/log/20131223T070301Z.log.html.gz</a></p>
Ruby master - Feature #8850 (Assigned): Convert Rational to decimal string
https://redmine.ruby-lang.org/issues/8850
2013-09-02T10:02:36Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>On Ruby 2.1.0, decimal literal is introduced.<br>
It generates Rational but it cannot easily convert to decimal string.<br>
You know, Rational#to_f is related to this but</p>
<ul>
<li>
<p>Float is not exact number<br>
** 0.123456789123456789r.to_f.to_s #=> "0.12345678912345678"</p>
</li>
<li>
<p>it can't handle recursive decimal<br>
** (151/13r).to_f.to_s #=> "11.615384615384615"</p>
</li>
<li>
<p>the method name<br>
** to_decimal<br>
** to_decimal_string<br>
** to_s(format: :decimal)<br>
** extend sprintf</p>
</li>
<li>
<p>how does it express recursive decimal<br>
** (151/13r).to_decimal_string #=> "11.615384..."<br>
** (151/13r).to_decimal_string #=> "11.(615384)"</p>
</li>
</ul>
<p>Example implementation is following.<br>
Its result is<br>
** 0.123456789123456789r.to_f.to_s #=> "0.123456789123456789"<br>
** (151/13r).to_f.to_s #=> "11.(615384)"</p>
<pre><code>class Rational
def to_decimal_string(base=10)
n = numerator
d = denominator
r, n = n.divmod d
str = r.to_s(base)
return str if n == 0
h = {}
str << '.'
n *= base
str.size.upto(Float::INFINITY) do |i|
r, n = n.divmod d
if n == 0
str << r.to_s(base)
break
elsif h.key? n
str[h[n], 0] = '('
str << ')'
break
else
str << r.to_s(base)
h[n] = i
n *= base
end
end
str
end
end
</code></pre>
Ruby master - Bug #8782 (Closed): Don't set rl_getc_function on editline
https://redmine.ruby-lang.org/issues/8782
2013-08-12T16:31:55Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>r42402 以来 OS X 等の editline 環境では #define rl_getc(f) EOF が使われるようになってしまって残念なことになっていたわけですが、<br>
そもそも editline の readline wrapper は non ASCII に対応していません。<br>
(editline 自体には UTF-8 のみの対応が入ったが、readline wrapper は src/readline.c の _getc_function を経由するので non ASCII は化ける)</p>
<p>ので、いっそ rl_getc_function を使わないようにしてはどうでしょう。<br>
以下のようなパッチを当てると、readline なしの OS X の irb で日本語が使えるようになります。</p>
<p>diff --git a/ext/readline/extconf.rb b/ext/readline/extconf.rb<br>
index 0b121c1..bc0ee77 100644<br>
--- a/ext/readline/extconf.rb<br>
+++ b/ext/readline/extconf.rb<br>
@@ -94,4 +94,5 @@ readline.have_func("clear_history")<br>
readline.have_func("rl_redisplay")<br>
readline.have_func("rl_insert_text")<br>
readline.have_func("rl_delete_text")<br>
+readline.have_func("el_init")<br>
create_makefile("readline")<br>
diff --git a/ext/readline/readline.c b/ext/readline/readline.c<br>
index 0f76d1a..85109f0 100644<br>
--- a/ext/readline/readline.c<br>
+++ b/ext/readline/readline.c<br>
@@ -130,12 +130,7 @@ static VALUE readline_instream;<br>
static VALUE readline_outstream;</p>
<a name="if-defined-HAVE_RL_GETC_FUNCTION"></a>
<h2 >#if defined HAVE_RL_GETC_FUNCTION<a href="#if-defined-HAVE_RL_GETC_FUNCTION" class="wiki-anchor">¶</a></h2>
<h2>-#ifndef HAVE_RL_GETC<br>
-#define rl_getc(f) EOF<br>
-#endif</h2>
<p>-static int readline_getc(FILE *);<br>
+# ifndef HAVE_EL_INIT<br>
static int<br>
readline_getc(FILE *input)<br>
{<br>
@@ -187,6 +182,7 @@ readline_getc(FILE *input)<br>
#endif<br>
return FIX2INT(c);<br>
}<br>
+# endif<br>
#elif defined HAVE_RL_EVENT_HOOK<br>
#define BUSY_WAIT 0</p>
<p>@@ -1771,7 +1767,9 @@ Init_readline()<br>
/* libedit check rl_getc_function only when rl_initialize() is called, <em>/<br>
/</em> and using_history() call rl_initialize(). <em>/<br>
/</em> This assignment should be placed before using_history() */<br>
+# ifndef HAVE_EL_INIT<br>
rl_getc_function = readline_getc;<br>
+# endif<br>
#elif defined HAVE_RL_EVENT_HOOK<br>
rl_event_hook = readline_event;<br>
#endif</p>
Ruby master - Feature #8734 (Closed): irbに複数行履歴機能が欲しい
https://redmine.ruby-lang.org/issues/8734
2013-08-05T16:22:48Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>現在のirbはクラス定義やメソッド定義のような複数行にわたるものを書くと、<br>
実行結果は閉じるまで返ってこないのに、履歴は一行ごとにバラバラになってしまい、とても不便です。<br>
なので、zshのように、複数行をまとめて履歴として扱えるようになって欲しいです。<br>
参考: <a href="http://news.mynavi.jp/column/zsh/003/index.html" class="external">http://news.mynavi.jp/column/zsh/003/index.html</a></p>
Ruby master - Feature #8678 (Assigned): Allow invalid string to work with regexp
https://redmine.ruby-lang.org/issues/8678
2013-07-24T14:47:22Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Legacy Ruby 1.8 could regexp match with broken strings.<br>
People can find characters from binary data on the age.</p>
<p>After Ruby 1.9, Ruby raises Exception if it does regexp match with broken strings.<br>
So it became hard to work with character-wise regexp matching with binary data.</p>
<p>Following patch allows it with the constant Regexp::LOOSEENCODING.</p>
<p>commit eb0111ff7ae3f563ce201c4a5f724f121336d42d<br>
Author: NARUSE, Yui <a href="mailto:naruse@ruby-lang.org" class="email">naruse@ruby-lang.org</a><br>
Date: Mon Jul 22 05:37:44 2013 +0900</p>
<pre><code>* Regexp
* New constant:
* Regexp::ENCODINGLOOSE: declare execute matching even if the target string
is invalid byte sequence. [experimental]
</code></pre>
<p>diff --git a/NEWS b/NEWS<br>
index f5fe388..ade0b03 100644<br>
--- a/NEWS<br>
+++ b/NEWS<br>
@@ -35,6 +35,11 @@ with all sufficient information, see the ChangeLog file.</p>
<ul>
<li>misc
<ul>
<li>Mutex#owned? is no longer experimental.</li>
</ul>
</li>
</ul>
<p>+* Regexp</p>
<ul>
<li>
<ul>
<li>New constant:</li>
</ul>
</li>
<li>
<ul>
<li>Regexp::ENCODINGLOOSE: declare execute matching even if the target string</li>
</ul>
</li>
<li>
<pre><code> is invalid byte sequence. [experimental]
</code></pre>
</li>
<li>
</ul>
<ul>
<li>String
<ul>
<li>New methods:
<ul>
<li>String#scrub and String#scrub! verify and fix invalid byte sequence.<br>
diff --git a/re.c b/re.c<br>
index e5cc79d..230a2e0 100644<br>
--- a/re.c<br>
+++ b/re.c<br>
@@ -256,6 +256,7 @@ rb_memsearch(const void *x0, long m, const void *y0, long n, rb_encoding *enc)</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>#define REG_LITERAL FL_USER5<br>
#define REG_ENCODING_NONE FL_USER6<br>
+#define REG_ENCODING_LOOSE FL_USER7</p>
<p>#define KCODE_FIXED FL_USER4</p>
<p>@@ -263,6 +264,7 @@ rb_memsearch(const void *x0, long m, const void *y0, long n, rb_encoding *enc)<br>
(ONIG_OPTION_IGNORECASE|ONIG_OPTION_MULTILINE|ONIG_OPTION_EXTEND)<br>
#define ARG_ENCODING_FIXED 16<br>
#define ARG_ENCODING_NONE 32<br>
+#define ARG_ENCODING_LOOSE 64</p>
<p>static int<br>
char_to_option(int c)<br>
@@ -1251,7 +1253,8 @@ rb_reg_prepare_enc(VALUE re, VALUE str, int warn)<br>
{<br>
rb_encoding *enc = 0;</p>
<ul>
<li>if (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) {</li>
</ul>
<ul>
<li>if (!(RBASIC(re)->flags & REG_ENCODING_LOOSE) &&</li>
<li>
<pre><code> rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) {
rb_raise(rb_eArgError,
"invalid byte sequence in %s",
rb_enc_name(rb_enc_get(str)));
</code></pre>
</li>
</ul>
<p>@@ -2433,6 +2436,9 @@ rb_reg_initialize(VALUE obj, const char *s, long len, rb_encoding *enc,<br>
if (options & ARG_ENCODING_NONE) {<br>
re->basic.flags |= REG_ENCODING_NONE;<br>
}</p>
<ul>
<li>
<p>if (options & ARG_ENCODING_LOOSE) {</p>
</li>
<li>
<pre><code> re->basic.flags |= REG_ENCODING_LOOSE;
</code></pre>
</li>
<li>
<p>}</p>
<p>re->ptr = make_regexp(RSTRING_PTR(unescaped), RSTRING_LEN(unescaped), enc,<br>
options & ARG_REG_OPTION_MASK, err,<br>
@@ -3091,6 +3097,7 @@ rb_reg_options(VALUE re)<br>
options = RREGEXP(re)->ptr->options & ARG_REG_OPTION_MASK;<br>
if (RBASIC(re)->flags & KCODE_FIXED) options |= ARG_ENCODING_FIXED;<br>
if (RBASIC(re)->flags & REG_ENCODING_NONE) options |= ARG_ENCODING_NONE;</p>
</li>
<li>
<p>if (RBASIC(re)->flags & REG_ENCODING_LOOSE) options |= ARG_ENCODING_LOOSE;<br>
return options;<br>
}</p>
</li>
</ul>
<p>@@ -3579,6 +3586,8 @@ Init_Regexp(void)<br>
rb_define_const(rb_cRegexp, "FIXEDENCODING", INT2FIX(ARG_ENCODING_FIXED));<br>
/* see Regexp.options and Regexp.new */<br>
rb_define_const(rb_cRegexp, "NOENCODING", INT2FIX(ARG_ENCODING_NONE));</p>
<ul>
<li>
<p>/* see Regexp.options and Regexp.new */</p>
</li>
<li>
<p>rb_define_const(rb_cRegexp, "LOOSEENCODING", INT2FIX(ARG_ENCODING_LOOSE));</p>
<p>rb_global_variable(&reg_cache);</p>
</li>
</ul>
<p>diff --git a/string.c b/string.c<br>
index 1d784e3..caf0baf 100644<br>
--- a/string.c<br>
+++ b/string.c<br>
@@ -3970,7 +3970,7 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)<br>
cp = sp;<br>
str_enc = STR_ENC_GET(str);<br>
rb_enc_associate(dest, str_enc);</p>
<ul>
<li>ENC_CODERANGE_SET(dest, rb_enc_asciicompat(str_enc) ? ENC_CODERANGE_7BIT : ENC_CODERANGE_VALID);</li>
</ul>
<ul>
<li>
<p>/<em>ENC_CODERANGE_SET(dest, rb_enc_asciicompat(str_enc) ? ENC_CODERANGE_7BIT : ENC_CODERANGE_VALID);</em>/</p>
<p>do {<br>
n++;<br>
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb<br>
index 11e86ec..b8f6897 100644<br>
--- a/test/ruby/test_regexp.rb<br>
+++ b/test/ruby/test_regexp.rb<br>
@@ -8,6 +8,10 @@ class TestRegexp < Test::Unit::TestCase<br>
$VERBOSE = nil<br>
end</p>
</li>
<li>
<p>def u(str)</p>
</li>
<li>
<p>str.dup.force_encoding(Encoding::UTF_8)</p>
</li>
<li>
<p>end</p>
</li>
<li>
<p>def teardown<br>
$VERBOSE = @verbose<br>
end<br>
@@ -958,6 +962,17 @@ class TestRegexp < Test::Unit::TestCase<br>
}<br>
end</p>
</li>
<li>
<p>def test_encoding_loose</p>
</li>
<li>
<p>str = u("\x80\xE3\x81\x82\x81")</p>
</li>
<li>
<p>assert_equal(0, Regexp.new(".", Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(1, Regexp.new(u('\p{Any}'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(1, Regexp.new("\u3042", Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(1, Regexp.new(u('\p{Hiragana}'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(0, Regexp.new(u('\A.\p{Hiragana}.\z'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>str = u("\xf1\x80\xE3\x81\x82\x81")</p>
</li>
<li>
<p>assert_equal(0, Regexp.new(u('\A..\p{Hiragana}.\z'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>end</p>
</li>
<li>
<a name="This-assertion-is-for-porting-x2-tests-in-testpypy-of-Onigmo"></a>
<h1 >This assertion is for porting x2() tests in testpy.py of Onigmo.<a href="#This-assertion-is-for-porting-x2-tests-in-testpypy-of-Onigmo" class="wiki-anchor">¶</a></h1>
<p>def assert_match_at(re, str, positions, msg = nil)<br>
re = Regexp.new(re) unless re.is_a?(Regexp)</p>
</li>
</ul>
Ruby master - Feature #8675 (Closed): Add Readline.point=(pos)
https://redmine.ruby-lang.org/issues/8675
2013-07-24T03:03:13Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>r42146 でのテスト修正で \A を入力しているのですが、rl_point を直接いじった方が正しい気がするので。</p>
<p>diff --git a/ext/readline/readline.c b/ext/readline/readline.c<br>
index 714b08c..03ab724 100644<br>
--- a/ext/readline/readline.c<br>
+++ b/ext/readline/readline.c<br>
@@ -808,6 +808,12 @@ readline_s_get_point(VALUE self)<br>
{<br>
return INT2NUM(rl_point);<br>
}<br>
+static VALUE<br>
+readline_s_set_point(VALUE self, VALUE pos)<br>
+{</p>
<ul>
<li>rl_point = NUM2INT(pos);</li>
<li>return pos;<br>
+}<br>
#else<br>
#define readline_s_get_point rb_f_notimplement<br>
#endif<br>
@@ -1761,6 +1767,8 @@ Init_readline()<br>
readline_s_get_line_buffer, 0);<br>
rb_define_singleton_method(mReadline, "point",<br>
readline_s_get_point, 0);</li>
<li>rb_define_singleton_method(mReadline, "point=",</li>
<li>
<pre><code> readline_s_set_point, 1);
</code></pre>
rb_define_singleton_method(mReadline, "set_screen_size",<br>
readline_s_set_screen_size, 2);<br>
rb_define_singleton_method(mReadline, "get_screen_size",</li>
</ul>
Ruby master - Feature #8526 (Closed): gemify tk
https://redmine.ruby-lang.org/issues/8526
2013-06-14T10:22:28Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>tk を Ruby のリポジトリから外しませんか。</p>
<p>そもそも tk はサイズベースで言えば、約69MBのRubyリポジトリのうち、8.8MBを占める巨大なライブラリでかつ、<br>
ビルドに際して多くのライブラリを必要とするため、従前より周囲の目が厳しいライブラリでありましたが、<br>
これまでは精力的にメンテされている永井さんに敬意を払って、本格的な削除の提案はされて来ませんでした。</p>
<p>しかし、最近は活動が鈍り、#5199 <a class="issue tracker-4 status-5 priority-4 priority-default closed" title="Backport: Ruby 1.9.3 fails to compile with tcl/tk on s390x (Closed)" href="https://redmine.ruby-lang.org/issues/5465">#5465</a> <a class="issue tracker-1 status-6 priority-4 priority-default closed" title="Bug: compile error for ext/tk/tcltklib.c: ‘ruby_errinfo’ undeclared (Rejected)" href="https://redmine.ruby-lang.org/issues/5686">#5686</a> <a class="issue tracker-1 status-6 priority-4 priority-default closed" title="Bug: Tk::Scrollable の include が成功しない? (Rejected)" href="https://redmine.ruby-lang.org/issues/7000">#7000</a> <a class="issue tracker-1 status-6 priority-4 priority-default closed" title="Bug: Tkで,コマンドにforkを入れると,イベント実行時にクラッシュする (Rejected)" href="https://redmine.ruby-lang.org/issues/7884">#7884</a> <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: "require 'tk'" segfaults on 64-bit linux with Tk 8.6 (Closed)" href="https://redmine.ruby-lang.org/issues/8000">#8000</a> <a class="issue tracker-4 status-5 priority-4 priority-default closed" title="Backport: Tk::Canvas.create raise if type TkcItem (Closed)" href="https://redmine.ruby-lang.org/issues/8319">#8319</a> <a class="issue tracker-1 status-8 priority-4 priority-default closed" title="Bug: Can't build tcl/tk extensions after updating Debian/Ubuntu package (Third Party's Issue)" href="https://redmine.ruby-lang.org/issues/8435">#8435</a> が残タスクとして残っています。<br>
リリースマネージャとしては、このような状況下ではtkをRubyのリポジトリから外していただいて、<br>
gem等で永井さんのペースでメンテしていただくのがよいのではないでしょうか。</p>
Ruby master - Bug #8492 (Closed): ObjectSpace.after_gc_start_hook aborts with GC.stress
https://redmine.ruby-lang.org/issues/8492
2013-06-05T12:45:13Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>以下を実行すると assert(during_gc > 0) に失敗して abort します。<br>
ruby -robjspace -e'ObjectSpace.after_gc_start_hook=proc{};GC.stress=true;{}'<br>
gc.c:3818 の<br>
gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_START, 0 /* TODO: pass minor/immediate flag? */);<br>
実行後に、during_gc が 0 になっている模様。</p>
Ruby master - Bug #8484 (Closed): Restoring conditions through the ruby method call during VM pro...
https://redmine.ruby-lang.org/issues/8484
2013-06-04T12:33:15Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>r41041 で、ブロック呼び出し前の VM 内の処理中に Ruby のメソッドが何らかの理由で呼ばれると argv が壊れるという問題を直しました。<br>
具体的には、</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">y</span> <span class="o">=</span> <span class="no">Object</span><span class="p">.</span><span class="nf">new</span>
<span class="k">def</span> <span class="nc">y</span><span class="o">.</span><span class="nf">s</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
<span class="k">yield</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">m</span> <span class="o">=</span> <span class="no">Object</span><span class="p">.</span><span class="nf">new</span>
<span class="k">def</span> <span class="nc">m</span><span class="o">.</span><span class="nf">method_missing</span><span class="p">(</span><span class="o">*</span><span class="n">a</span><span class="p">)</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="n">assert_equal</span> <span class="p">[</span><span class="n">m</span><span class="p">,</span> <span class="kp">nil</span><span class="p">],</span> <span class="n">y</span><span class="p">.</span><span class="nf">s</span><span class="p">(</span><span class="n">m</span><span class="p">){</span><span class="o">|</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="o">|</span><span class="p">[</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">]}</span>
</code></pre>
<p>のようなコードの場合、</p>
<ul>
<li>
<code>y.s</code> に <code>m</code> と <code>block</code> が渡される</li>
<li>
<code>y.s</code> で <code>yield(a)</code> が呼ばれる</li>
<li>
<code>argv</code>が設定される</li>
<li>
<code>vm_invoke_block</code> 内の <code>VALUE * const rsp = GET_SP() - ci->argc; SET_SP(rsp);</code> で <code>argv</code> の先頭に <code>sp</code> が設定される</li>
<li><code>vm_yield_setup_args</code></li>
<li><code>vm_yield_setup_block_args</code></li>
<li>
<code>y.s</code> のブロックパラメータは2つなのに、引数は一つなので、<code>a.to_ary</code> が呼ばれる (<code>rb_check_array_type(arg0)</code>)</li>
<li>
<code>method_missing</code> が呼ばれる</li>
<li>
<code>super</code> が呼ばれる (このへんで <code>vm _push_frame</code> が呼ばれる)</li>
<li>
<code>vm_push_frame</code>のinitialize local variablesのところで<code>argv</code>に<code>nil</code>が代入されて破壊される</li>
</ul>
<p>で、これ自体は <code>argv</code> を対比しておいて戻せばよいです。<br>
また、<code>SET_SP(rsp)</code>のあたりは、ささださん曰く「 <code>argv</code> に書き込みがない、という前提でそこは作ってるんだよね」だそうな。<br>
しかし、「そんな前提わかるかっ」ですし、<br>
methodの方は <code>SAVE_RESTORE_CI(tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a"), ci);</code> ともうちょっとわかりやすく書いてあるので、<br>
「頂いた問題点を元に、一度全部総点検が必要そうです」とのことですので、お願いします。</p>
Ruby master - Feature #8414 (Closed): String#scrub!
https://redmine.ruby-lang.org/issues/8414
2013-05-17T16:38:09Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>r40390 [Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Replacing ill-formed subsequencce (Closed)" href="https://redmine.ruby-lang.org/issues/6752">#6752</a>] で で追加した String#scrub ですが、破壊的メソッド版も追加していいでしょうか。<br>
lib/uri/common.rb いじっていて、欲しくなったので。</p>
Ruby master - Misc #8288 (Closed): Ruby 2.1.0 release engeneering
https://redmine.ruby-lang.org/issues/8288
2013-04-19T03:31:49Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>This is meta issue for releasing Ruby 2.1.0</p>
<p>see also <a href="https://bugs.ruby-lang.org/versions/27" class="external">https://bugs.ruby-lang.org/versions/27</a></p>
Backport200 - Backport #8266 (Closed): Backport r40216 (fiddle's mprotect)
https://redmine.ruby-lang.org/issues/8266
2013-04-14T23:23:40Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>r40216 を backport お願いします。<br>
とりあえず segv はしなくなります。</p>
Ruby master - Feature #8217 (Closed): OpenSSL::BN.new with integers
https://redmine.ruby-lang.org/issues/8217
2013-04-04T15:59:31Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Current OpenSSL::BN.new gets only strings, so users must do integer.to_s, it costs extra resource.<br>
Therefore I propose OpenSSL::BN.new to allow Fixnu/Bignum.</p>
<p>diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c<br>
index 1038135..1f1ebba 100644<br>
--- a/ext/openssl/ossl_bn.c<br>
+++ b/ext/openssl/ossl_bn.c<br>
@@ -120,6 +120,44 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)<br>
base = NUM2INT(bs);<br>
}</p>
<ul>
<li>if (RB_TYPE_P(str, T_FIXNUM)) {</li>
<li>long i;</li>
<li>unsigned char <em>bin = (unsigned char</em>)ALLOC_N(long, 1);</li>
<li>long n = FIX2LONG(str);</li>
<li>unsigned long un = abs(n);</li>
<li>
<li>for (i = sizeof(VALUE) - 1; 0 <= i; i--) {</li>
<li>
<pre><code> bin[i] = un&0xff;
</code></pre>
</li>
<li>
<pre><code> un >>= 8;
</code></pre>
</li>
<li>}</li>
<li>
<li>GetBN(self, bn);</li>
<li>if (!BN_bin2bn(bin, sizeof(long), bn)) {</li>
<li>
<pre><code> ossl_raise(eBNError, NULL);
</code></pre>
</li>
<li>}</li>
<li>if (n < 0) BN_set_negative(bn, 1);</li>
<li>return self;</li>
<li>}</li>
<li>else if (RB_TYPE_P(str, T_BIGNUM)) {</li>
<li>long i, j;</li>
<li>BDIGIT *ds = RBIGNUM_DIGITS(str);</li>
<li>unsigned char <em>bin = (unsigned char</em>)ALLOC_N(BDIGIT, RBIGNUM_LEN(str));</li>
<li>
<li>for (i = 0; RBIGNUM_LEN(str) > i; i++) {</li>
<li>
<pre><code> BDIGIT v = ds[i];
</code></pre>
</li>
<li>
<pre><code> for (j = sizeof(BDIGIT) - 1; 0 <= j; j--) {
</code></pre>
</li>
<li>
<pre><code> bin[(RBIGNUM_LEN(str)-1-i)*sizeof(BDIGIT)+j] = v&0xff;
</code></pre>
</li>
<li>
<pre><code> v >>= 8;
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>}</li>
<li>
<li>GetBN(self, bn);</li>
<li>if (!BN_bin2bn(bin, sizeof(BDIGIT)*RBIGNUM_LEN(str), bn)) {</li>
<li>
<pre><code> ossl_raise(eBNError, NULL);
</code></pre>
</li>
<li>}</li>
<li>if (!RBIGNUM_SIGN(str)) BN_set_negative(bn, 1);</li>
<li>return self;</li>
<li>}<br>
if (RTEST(rb_obj_is_kind_of(str, cBN))) {<br>
BIGNUM *other;</li>
</ul>
<p>diff --git a/test/openssl/test_bn.rb b/test/openssl/test_bn.rb<br>
index af1c72c..758cc54 100644<br>
--- a/test/openssl/test_bn.rb<br>
+++ b/test/openssl/test_bn.rb<br>
@@ -8,6 +8,13 @@ class OpenSSL::TestBN < Test::Unit::TestCase<br>
end</p>
<p>def test_integer_to_bn</p>
<ul>
<li>assert_equal(999.to_bn, OpenSSL::BN.new(999))</li>
<li>assert_equal((2 ** 107 - 1).to_bn, OpenSSL::BN.new(2 ** 107 - 1))</li>
<li>assert_equal(-999.to_bn, OpenSSL::BN.new(-999))</li>
<li>assert_equal((-(2 ** 107 - 1)).to_bn, OpenSSL::BN.new(-(2 ** 107 - 1)))</li>
<li>end</li>
<li>
<li>def test_integer_str_to_bn<br>
assert_equal(999.to_bn, OpenSSL::BN.new(999.to_s(16), 16))<br>
assert_equal((2 ** 107 - 1).to_bn, OpenSSL::BN.new((2 ** 107 - 1).to_s(16), 16))<br>
end</li>
</ul>
Ruby master - Bug #8157 (Closed): How to write document for __LINE__, __FILE__, __END__
https://redmine.ruby-lang.org/issues/8157
2013-03-24T01:12:41Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>How do I write document for <strong>LINE</strong>, <strong>FILE</strong>, <strong>END</strong> ?</p>
<p>Moreover, __ is expressed as _ in rdoc.<br>
How can I avoid it?</p>
Backport193 - Backport #8076 (Closed): Lookbehind assertion fails with /m mode enabled
https://redmine.ruby-lang.org/issues/8076
2013-03-11T19:52:38Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Lookbehind assertions fail if they are longer than one character, and if dotall mode is set.</p>
<p>irb(main):001:0> "foo" =~ /(?<=f).<em>/m<br>
=> 1<br>
irb(main):002:0> "foo" =~ /(?<=fo).</em>/m<br>
=> nil</p>
<p>The latter should have matched the "o". This only seems to happen with dotall mode turned on (dot matches newline); without it, everything is OK:</p>
<p>irb(main):003:0> "foo" =~ /(?<=f).<em>/<br>
=> 1<br>
irb(main):004:0> "foo" =~ /(?<=fo).</em>/<br>
=> 2</p>
Backport193 - Backport #7896 (Closed): Can't test rb_iter_break with extensions
https://redmine.ruby-lang.org/issues/7896
2013-02-21T12:05:29Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>If you test rb_iter_break() with some extension library like trunk's ext/-test-/iter/break.c, it will cause SEGV on 1.9.3.<br>
It won't happen on 2.0 because r34369 is accidentally fix it with below patch.</p>
<p>I noticed this because RubySpec added a test for rb_spec_iter (4db31b04954118e66ac1d6353ebf4106cb2b419b) and hit this.</p>
<h1>% svn di<br>
Index: vm.c</h1>
<p>--- vm.c (revision 39346)<br>
+++ vm.c (working copy)<br>
@@ -1370,6 +1370,7 @@<br>
*th->cfp->sp++ = (GET_THROWOBJ_VAL(err));<br>
#endif<br>
}</p>
<ul>
<li>
<pre><code> th->state = 0;
th->errinfo = Qnil;
goto vm_loop_start;
}
</code></pre>
</li>
</ul>
Backport193 - Backport #7587 (Closed): r35924
https://redmine.ruby-lang.org/issues/7587
2012-12-18T19:56:48Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>make -j したときにこけるので r35924 を backport してください</p>
Ruby master - Bug #7302 (Closed): r37497 changes rb_enumeratorize without NEWS
https://redmine.ruby-lang.org/issues/7302
2012-11-07T19:53:08Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>r37497 [Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Enumerable#size (Closed)" href="https://redmine.ruby-lang.org/issues/6636">#6636</a>] changed the prototype of rb_enumeratorize.<br>
It is public Ruby CAPI.</p>
<p>I think it shouldn't be changed and add another CAPI like rb_enumeratorize_with_size.<br>
At least a description should be add to NEWS</p>
Backport193 - Backport #7169 (Closed): r37169
https://redmine.ruby-lang.org/issues/7169
2012-10-16T09:43:05Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>以下をマージお願いします。</p>
<p>commit 78e3185a20d9307c98fecca6d3bacfb8f2c271b8<br>
Author: naruse <a href="mailto:naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e" class="email">naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e</a><br>
Date: Sat Oct 13 01:03:41 2012</p>
<pre><code>use tty(1) to check if /dev/tty is usable or not
</code></pre>
<p><a href="http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?revision=37169&view=revision" class="external">http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?revision=37169&view=revision</a></p>
Ruby master - Feature #6936 (Closed): Forbid singleton class and instance variabls for float
https://redmine.ruby-lang.org/issues/6936
2012-08-27T08:12:45Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>[Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Introduce Flonum technique to speedup floating computation on th 64bit environment (Closed)" href="https://redmine.ruby-lang.org/issues/6763">#6763</a>] などで議論されていた flonum が r36798 でが入ったわけですが、</p>
<ol>
<li>Float のオブジェクトID の仕様が変更</li>
<li>flonum な float に特異メソッドが追加不可</li>
<li>flonum な float に特異クラスが作成不可</li>
<li>flonum な float は同じ値同士でインスタンス変数が共有される</li>
</ol>
<p>といった非互換が存在します。<br>
もっとも、1. は通常意識するはずのないところですし、2. は元から禁止されています。<br>
気になるのは 3. と 4. で、これは 1.9.3 と挙動が異なるだけでなく、<br>
32bit 環境での 2.0 や、64bit環境の flonum でない float オブジェクトとも挙動が異なります。</p>
<p>実際問題として実害はないような気もしますが、このような違いが極めて実装上の問題で、<br>
Ruby 上から見えないところに存在するのは気持ち悪く感じます。</p>
<p>よって、以下のようにするとよいのではないでしょうか。</p>
<ul>
<li>flonum でない float でも特異クラスの作成を禁止</li>
<li>float へのインスタンス変数作成を禁止</li>
</ul>
<p>後者の具体的手法はいくつかあると思いますが、即値は最初から frozen にしておくとかもありかなと思っています。</p>
<p>話を発散させると、この話は true, false, nil, Fixnum, Symbol のような即値から、<br>
Bignum や Time のような immutable っぽいオブジェクトにも当てはまる気がしています。</p>
Ruby master - Feature #6767 (Closed): Utility method to get a duplicated string whose encoding is...
https://redmine.ruby-lang.org/issues/6767
2012-07-22T03:20:31Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>ある String を ASCII-8BIT にしたいことはしばしばあります。<br>
それだけならばまだ force_encoding しろよという話なのですが、<br>
<a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Bitwise string operations (Rejected)" href="https://redmine.ruby-lang.org/issues/6361">#6361</a> の例のように、バイナリ文字列にさらにバイナリ文字列を結合していく場合、<br>
毎行毎行 force_encoding を書いていくのにはつらいものがあります。</p>
<p>解決案としては、<br>
(1) バイナリリテラルの導入<br>
(2) dup.force_encoding(Encoding::ASCII_8BIT) する短いメソッドを追加<br>
(3) ASCII-8BIT に他のエンコーディングの文字列を結合した場合は暗黙に force_encoding<br>
が考えられます。</p>
<p>しかし、(1) は文法拡張なのでハードルが高く、(3) は方々で議論になっている通りです。<br>
よって、(2) が妥当ではないかと思います。</p>
<p>名前をまつもとさん提案の String#b としたパッチを以下の通り添付します。</p>
<p>diff --git a/string.c b/string.c<br>
index d038835..76cbc36 100644<br>
--- a/string.c<br>
+++ b/string.c<br>
@@ -601,7 +601,7 @@ rb_str_export_to_enc(VALUE str, rb_encoding *enc)<br>
}</p>
<p>static VALUE<br>
-str_replace_shared(VALUE str2, VALUE str)<br>
+str_replace_shared_without_enc(VALUE str2, VALUE str)<br>
{<br>
if (RSTRING_LEN(str) <= RSTRING_EMBED_LEN_MAX) {<br>
STR_SET_EMBED(str2);<br>
@@ -616,8 +616,14 @@ str_replace_shared(VALUE str2, VALUE str)<br>
RSTRING(str2)->as.heap.aux.shared = str;<br>
FL_SET(str2, ELTS_SHARED);<br>
}</p>
<ul>
<li>rb_enc_cr_str_exact_copy(str2, str);</li>
</ul>
<ul>
<li>return str2;<br>
+}</li>
</ul>
<p>+static VALUE<br>
+str_replace_shared(VALUE str2, VALUE str)<br>
+{</p>
<ul>
<li>str_replace_shared_without_enc(str2, str);</li>
<li>rb_enc_cr_str_exact_copy(str2, str);<br>
return str2;<br>
}</li>
</ul>
<p>@@ -7340,6 +7346,23 @@ rb_str_force_encoding(VALUE str, VALUE enc)</p>
<p>/*</p>
<ul>
<li>call-seq:</li>
</ul>
<ul>
<li>
<ul>
<li>
<pre><code>str.b -> str
</code></pre>
</li>
</ul>
</li>
<li>
<ul>
<li>
</ul>
</li>
<li>
<ul>
<li>Returns a copied string whose encoding is ASCII-8BIT.</li>
</ul>
</li>
<li>*/</li>
<li>
</ul>
<p>+static VALUE<br>
+rb_str_b(VALUE str)<br>
+{</p>
<ul>
<li>VALUE str2 = str_alloc(rb_cString);</li>
<li>str_replace_shared_without_enc(str2, str);</li>
<li>OBJ_INFECT(str2, str);</li>
<li>ENC_CODERANGE_SET(str2, ENC_CODERANGE_VALID);</li>
<li>return str2;<br>
+}</li>
<li>
</ul>
<p>+/*</p>
<ul>
<li>
<ul>
<li>
<p>call-seq:</p>
</li>
<li>
<pre><code>str.valid_encoding? -> true or false
</code></pre>
</li>
<li>
<li>
<p>Returns true for a string which encoded correctly.<br>
@@ -7969,6 +7992,7 @@ Init_String(void)</p>
<p>rb_define_method(rb_cString, "encoding", rb_obj_encoding, 0); /* in encoding.c */<br>
rb_define_method(rb_cString, "force_encoding", rb_str_force_encoding, 1);</p>
</li>
</ul>
</li>
<li>rb_define_method(rb_cString, "b", rb_str_b, 0);<br>
rb_define_method(rb_cString, "valid_encoding?", rb_str_valid_encoding_p, 0);<br>
rb_define_method(rb_cString, "ascii_only?", rb_str_is_ascii_only_p, 0);</li>
</ul>
<p>diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb<br>
index dfcaa94..3a4bca7 100644<br>
--- a/test/ruby/test_m17n.rb<br>
+++ b/test/ruby/test_m17n.rb<br>
@@ -1469,4 +1469,14 @@ class TestM17N < Test::Unit::TestCase<br>
yield(*strs)<br>
end<br>
end<br>
+</p>
<ul>
<li>def test_str_b</li>
<li>s = "\u3042"</li>
<li>assert_equal(a("\xE3\x81\x82"), s.b)</li>
<li>assert_equal(Encoding::ASCII_8BIT, s.b.encoding)</li>
<li>s.taint</li>
<li>assert_equal(true, s.b.tainted?)</li>
<li>s.untrust</li>
<li>assert_equal(true, s.b.untrusted?)</li>
<li>end<br>
end</li>
</ul>
Ruby master - Feature #6752 (Closed): Replacing ill-formed subsequencce
https://redmine.ruby-lang.org/issues/6752
2012-07-19T11:42:58Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
== 概要<br>
Stringになんらかの理由で不正なバイト列が含まれている時に、それを置換文字で置き換えたい。</p>
<p>== ユースケース<br>
実際に確認されているユースケースは以下の通りです。</p>
<ul>
<li>
<p>twitterのtitle</p>
</li>
<li>
<p>IRCのログ</p>
</li>
<li>
<p>ニコニコ動画の API</p>
</li>
<li>
<p>Webクローリング<br>
これらの不正なバイト列の生成過程は、おそらく、バイト単位で文字列を切り詰めた時に末尾が切れて、<br>
末尾がおかしい不正な文字列が作られます。(前二者)<br>
これをコンテナに入れたり結合することによって、途中にも混ざった文字列が作られます。(後二者)</p>
</li>
<li>
<p><a href="https://twitter.com/takahashim/status/18974040397" class="external">https://twitter.com/takahashim/status/18974040397</a></p>
</li>
<li>
<p><a href="https://twitter.com/n0kada/status/215674740705210368" class="external">https://twitter.com/n0kada/status/215674740705210368</a></p>
</li>
<li>
<p><a href="https://twitter.com/n0kada/status/215686490070585346" class="external">https://twitter.com/n0kada/status/215686490070585346</a></p>
</li>
<li>
<p><a href="https://twitter.com/hajimehoshi/status/215671146769682432" class="external">https://twitter.com/hajimehoshi/status/215671146769682432</a></p>
</li>
<li>
<p><a href="http://po-ru.com/diary/fixing-invalid-utf-8-in-ruby-revisited/" class="external">http://po-ru.com/diary/fixing-invalid-utf-8-in-ruby-revisited/</a></p>
</li>
<li>
<p><a href="http://stackoverflow.com/questions/2982677/ruby-1-9-invalid-byte-sequence-in-utf-8" class="external">http://stackoverflow.com/questions/2982677/ruby-1-9-invalid-byte-sequence-in-utf-8</a></p>
</li>
</ul>
<p>== 必要な引数: 置換文字<br>
省略可能、String。<br>
デフォルトは、Unicode系ならU+FFFD、それ以外では「?」。<br>
デフォルトが空文字でない理由は、削除してしまうことで、従来は存在しなかったトークンを作れてしまい、<br>
上位のレイヤーの脆弱性に繋がるからです。<br>
<a href="http://unicode.org/reports/tr36/#UTF-8_Exploit" class="external">http://unicode.org/reports/tr36/#UTF-8_Exploit</a></p>
<p>== API<br>
--- str.encode(str.encoding, invalid: replace, [replace: "〓"])</p>
<ul>
<li>CSI的じゃなくて気持ち悪い</li>
<li>iconv でできるのは glibc iconv か GNU libiconv に //IGNORE つけた時で他はできない</li>
<li>実装上のメリットは後述の通り、直感に反してあまりない(と思う)</li>
</ul>
<p>== 別メソッド</p>
<ul>
<li>新しいメソッドである</li>
<li>fix/repair invalid/illegal bytes/sequence あたりの名前か</li>
</ul>
<p>== 実装<br>
=== 鬼車ベース<br>
int ret = rb_enc_precise_mbclen(p, e, enc); して、<br>
MBCLEN_INVALID_P(ret) が真な時、何バイト目が不正なのかわからないのが微妙。<br>
ONIGENC_CONSTRUCT_MBCLEN_INVALID() がバイト数を取らないのが原因なので、<br>
鬼車のエンコーディングモジュール全てに影響してしまうため、修正困難。<br>
不正なバイトはほとんど存在しないと仮定して、効率を犠牲にすれば回避は可能。</p>
<p>=== transcodeベース<br>
UCS正規化なglibc iconv, GNU libiconv, Perl Encodeなどと違って、<br>
CSIなtranscodeでは、自分自身に変換する場合、<br>
エンコーディングごとに「何もしない」変換モジュールを用意しないといけない。</p>
<p>とりあえず鬼車ベースのコンセプト実装とテストを添付しておきます。</p>
<p>diff --git a/string.c b/string.c<br>
index d038835..4808f15 100644<br>
--- a/string.c<br>
+++ b/string.c<br>
@@ -7426,6 +7426,199 @@ rb_str_ellipsize(VALUE str, long len)<br>
return ret;<br>
}</p>
<p>+/*</p>
<ul>
<li>
<ul>
<li>call-seq:</li>
</ul>
</li>
<li>
<ul>
<li>str.fix_invalid -> new_str</li>
</ul>
</li>
<li>
<ul>
<li>
</ul>
</li>
<li>
<ul>
<li>If the string is well-formed, it returns self.</li>
</ul>
</li>
<li>
<ul>
<li>If the string has invalid byte sequence, repair it with given replacement</li>
</ul>
</li>
<li>
<ul>
<li>character.</li>
</ul>
</li>
<li>*/<br>
+VALUE<br>
+rb_str_fix_invalid(VALUE str)<br>
+{</li>
<li>int cr = ENC_CODERANGE(str);</li>
<li>rb_encoding *enc;</li>
<li>if (cr == ENC_CODERANGE_7BIT || cr == ENC_CODERANGE_VALID)</li>
<li>return rb_str_dup(str);</li>
<li>
<li>enc = STR_ENC_GET(str);</li>
<li>if (rb_enc_asciicompat(enc)) {</li>
<li>const char *p = RSTRING_PTR(str);</li>
<li>const char *e = RSTRING_END(str);</li>
<li>const char *p1 = p;</li>
<li>/* 10 should be enough for the usual use case,</li>
<li>
<ul>
<li>fixing a wrongly chopped character at the end of the string</li>
</ul>
</li>
<li>*/</li>
<li>long room = 10;</li>
<li>VALUE buf = rb_str_buf_new(RSTRING_LEN(str) + room);</li>
<li>const char *rep;</li>
<li>if (enc == rb_utf8_encoding())</li>
<li>
<pre><code> rep = "\xEF\xBF\xBD";
</code></pre>
</li>
<li>else</li>
<li>
<pre><code> rep = "?";
</code></pre>
</li>
<li>cr = ENC_CODERANGE_7BIT;</li>
<li>
<li>p = search_nonascii(p, e);</li>
<li>if (!p) {</li>
<li>
<pre><code> p = e;
</code></pre>
</li>
<li>}</li>
<li>while (p < e) {</li>
<li>
<pre><code> int ret = rb_enc_precise_mbclen(p, e, enc);
</code></pre>
</li>
<li>
<pre><code> if (MBCLEN_CHARFOUND_P(ret)) {
</code></pre>
</li>
<li>
<pre><code> if ((unsigned char)*p > 127) cr = ENC_CODERANGE_VALID;
</code></pre>
</li>
<li>
<pre><code> p += MBCLEN_CHARFOUND_LEN(ret);
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> else if (MBCLEN_INVALID_P(ret)) {
</code></pre>
</li>
<li>
<pre><code> const char *q;
</code></pre>
</li>
<li>
<pre><code> long clen = rb_enc_mbmaxlen(enc);
</code></pre>
</li>
<li>
<pre><code> if (p > p1) rb_str_buf_cat(buf, p1, p - p1);
</code></pre>
</li>
<li>
<pre><code> q = RSTRING_END(buf);
</code></pre>
</li>
<li>
<li>
<pre><code> if (e - p < clen) clen = e - p;
</code></pre>
</li>
<li>
<pre><code> if (clen < 3) {
</code></pre>
</li>
<li>
<pre><code> clen = 1;
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> else {
</code></pre>
</li>
<li>
<pre><code> long len = RSTRING_LEN(buf);
</code></pre>
</li>
<li>
<pre><code> clen--;
</code></pre>
</li>
<li>
<pre><code> rb_str_buf_cat(buf, p, clen);
</code></pre>
</li>
<li>
<pre><code> for (; clen > 1; clen--) {
</code></pre>
</li>
<li>
<pre><code> ret = rb_enc_precise_mbclen(q, q + clen, enc);
</code></pre>
</li>
<li>
<pre><code> if (MBCLEN_NEEDMORE_P(ret)) {
</code></pre>
</li>
<li>
<pre><code> break;
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> else if (MBCLEN_INVALID_P(ret)) {
</code></pre>
</li>
<li>
<pre><code> continue;
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> else {
</code></pre>
</li>
<li>
<pre><code> rb_bug("shouldn't reach here '%s'", q);
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> rb_str_set_len(buf, len);
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> p += clen;
</code></pre>
</li>
<li>
<pre><code> p1 = p;
</code></pre>
</li>
<li>
<pre><code> rb_str_buf_cat2(buf, rep);
</code></pre>
</li>
<li>
<pre><code> p = search_nonascii(p, e);
</code></pre>
</li>
<li>
<pre><code> if (!p) {
</code></pre>
</li>
<li>
<pre><code> p = e;
</code></pre>
</li>
<li>
<pre><code> break;
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> else if (MBCLEN_NEEDMORE_P(ret)) {
</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> rb_bug("shouldn't reach here");
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>}</li>
<li>if (p1 < p) {</li>
<li>
<pre><code> rb_str_buf_cat(buf, p1, p - p1);
</code></pre>
</li>
<li>}</li>
<li>if (p < e) {</li>
<li>
<pre><code> rb_str_buf_cat2(buf, rep);
</code></pre>
</li>
<li>
<pre><code> cr = ENC_CODERANGE_VALID;
</code></pre>
</li>
<li>}</li>
<li>ENCODING_CODERANGE_SET(buf, rb_enc_to_index(enc), cr);</li>
<li>return buf;</li>
<li>}</li>
<li>else if (rb_enc_dummy_p(enc)) {</li>
<li>return rb_str_dup(str);</li>
<li>}</li>
<li>else {</li>
<li>/* ASCII incompatible */</li>
<li>const char *p = RSTRING_PTR(str);</li>
<li>const char *e = RSTRING_END(str);</li>
<li>const char *p1 = p;</li>
<li>/* 10 should be enough for the usual use case,</li>
<li>
<ul>
<li>fixing a wrongly chopped character at the end of the string</li>
</ul>
</li>
<li>*/</li>
<li>long room = 10;</li>
<li>VALUE buf = rb_str_buf_new(RSTRING_LEN(str) + room);</li>
<li>const char *rep;</li>
<li>long mbminlen = rb_enc_mbminlen(enc);</li>
<li>static rb_encoding *utf16be;</li>
<li>static rb_encoding *utf16le;</li>
<li>static rb_encoding *utf32be;</li>
<li>static rb_encoding *utf32le;</li>
<li>if (!utf16be) {</li>
<li>
<pre><code> utf16be = rb_enc_find("UTF-16BE");
</code></pre>
</li>
<li>
<pre><code> utf16le = rb_enc_find("UTF-16LE");
</code></pre>
</li>
<li>
<pre><code> utf32be = rb_enc_find("UTF-32BE");
</code></pre>
</li>
<li>
<pre><code> utf32le = rb_enc_find("UTF-32LE");
</code></pre>
</li>
<li>}</li>
<li>if (enc == utf16be) {</li>
<li>
<pre><code> rep = "\xFF\xFD";
</code></pre>
</li>
<li>}</li>
<li>else if (enc == utf16le) {</li>
<li>
<pre><code> rep = "\xFD\xFF";
</code></pre>
</li>
<li>}</li>
<li>else if (enc == utf32be) {</li>
<li>
<pre><code> rep = "\x00\x00\xFF\xFD";
</code></pre>
</li>
<li>}</li>
<li>else if (enc == utf32le) {</li>
<li>
<pre><code> rep = "\xFD\xFF\x00\x00";
</code></pre>
</li>
<li>}</li>
<li>else {</li>
<li>
<pre><code> rep = "?";
</code></pre>
</li>
<li>}</li>
<li>
<li>while (p < e) {</li>
<li>
<pre><code> int ret = rb_enc_precise_mbclen(p, e, enc);
</code></pre>
</li>
<li>
<pre><code> if (MBCLEN_CHARFOUND_P(ret)) {
</code></pre>
</li>
<li>
<pre><code> p += MBCLEN_CHARFOUND_LEN(ret);
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> else if (MBCLEN_INVALID_P(ret)) {
</code></pre>
</li>
<li>
<pre><code> const char *q;
</code></pre>
</li>
<li>
<pre><code> long clen = rb_enc_mbmaxlen(enc);
</code></pre>
</li>
<li>
<pre><code> if (p > p1) rb_str_buf_cat(buf, p1, p - p1);
</code></pre>
</li>
<li>
<pre><code> q = RSTRING_END(buf);
</code></pre>
</li>
<li>
<li>
<pre><code> if (e - p < clen) clen = e - p;
</code></pre>
</li>
<li>
<pre><code> if (clen < mbminlen * 3) {
</code></pre>
</li>
<li>
<pre><code> clen = mbminlen;
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> else {
</code></pre>
</li>
<li>
<pre><code> long len = RSTRING_LEN(buf);
</code></pre>
</li>
<li>
<pre><code> clen -= mbminlen;
</code></pre>
</li>
<li>
<pre><code> rb_str_buf_cat(buf, p, clen);
</code></pre>
</li>
<li>
<pre><code> for (; clen > mbminlen; clen-=mbminlen) {
</code></pre>
</li>
<li>
<pre><code> ret = rb_enc_precise_mbclen(q, q + clen, enc);
</code></pre>
</li>
<li>
<pre><code> if (MBCLEN_NEEDMORE_P(ret)) {
</code></pre>
</li>
<li>
<pre><code> break;
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> else if (MBCLEN_INVALID_P(ret)) {
</code></pre>
</li>
<li>
<pre><code> continue;
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> else {
</code></pre>
</li>
<li>
<pre><code> rb_bug("shouldn't reach here '%s'", q);
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> rb_str_set_len(buf, len);
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> p += clen;
</code></pre>
</li>
<li>
<pre><code> p1 = p;
</code></pre>
</li>
<li>
<pre><code> rb_str_buf_cat2(buf, rep);
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> else if (MBCLEN_NEEDMORE_P(ret)) {
</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> rb_bug("shouldn't reach here");
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>}</li>
<li>if (p1 < p) {</li>
<li>
<pre><code> rb_str_buf_cat(buf, p1, p - p1);
</code></pre>
</li>
<li>}</li>
<li>if (p < e) {</li>
<li>
<pre><code> rb_str_buf_cat2(buf, rep);
</code></pre>
</li>
<li>}</li>
<li>ENCODING_CODERANGE_SET(buf, rb_enc_to_index(enc), ENC_CODERANGE_VALID);</li>
<li>return buf;</li>
<li>}<br>
+}</li>
<li>
</ul>
<p>/**********************************************************************</p>
<ul>
<li>Document-class: Symbol</li>
<li>
</ul>
<p>@@ -7882,6 +8075,7 @@ Init_String(void)<br>
rb_define_method(rb_cString, "getbyte", rb_str_getbyte, 1);<br>
rb_define_method(rb_cString, "setbyte", rb_str_setbyte, 2);<br>
rb_define_method(rb_cString, "byteslice", rb_str_byteslice, -1);</p>
<ul>
<li>
<p>rb_define_method(rb_cString, "fix_invalid", rb_str_fix_invalid, 0);</p>
<p>rb_define_method(rb_cString, "to_i", rb_str_to_i, -1);<br>
rb_define_method(rb_cString, "to_f", rb_str_to_f, 0);<br>
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb<br>
index 47f349c..2b0cfeb 100644<br>
--- a/test/ruby/test_string.rb<br>
+++ b/test/ruby/test_string.rb<br>
@@ -2031,6 +2031,29 @@ class TestString < Test::Unit::TestCase</p>
<p>assert_equal(u("\x82")+("\u3042"*9), ("\u3042"*10).byteslice(2, 28))<br>
end</p>
</li>
<li>
<li>
<p>def test_fix_invalid</p>
</li>
<li>
<p>assert_equal("\uFFFD\uFFFD\uFFFD", "\x80\x80\x80".fix_invalid)</p>
</li>
<li>
<p>assert_equal("\uFFFDA", "\xF4\x80\x80A".fix_invalid)</p>
</li>
<li>
<li>
<a name="exapmles-in-Unicode-610-D93b"></a>
<h1 >exapmles in Unicode 6.1.0 D93b<a href="#exapmles-in-Unicode-610-D93b" class="wiki-anchor">¶</a></h1>
</li>
<li>
<p>assert_equal("\x41\uFFFD\uFFFD\x41\uFFFD\x41",</p>
</li>
<li>
<pre><code> "\x41\xC0\xAF\x41\xF4\x80\x80\x41".fix_invalid)
</code></pre>
</li>
<li>
<p>assert_equal("\x41\uFFFD\uFFFD\uFFFD\x41",</p>
</li>
<li>
<pre><code> "\x41\xE0\x9F\x80\x41".fix_invalid)
</code></pre>
</li>
<li>
<p>assert_equal("\u0061\uFFFD\uFFFD\uFFFD\u0062\uFFFD\u0063\uFFFD\uFFFD\u0064",</p>
</li>
<li>
<pre><code> "\x61\xF1\x80\x80\xE1\x80\xC2\x62\x80\x63\x80\xBF\x64".fix_invalid)
</code></pre>
</li>
<li>
<li>
<p>assert_equal("abcdefghijklmnopqrstuvwxyz\u0061\uFFFD\uFFFD\uFFFD\u0062\uFFFD\u0063\uFFFD\uFFFD\u0064",</p>
</li>
<li>
<pre><code> "abcdefghijklmnopqrstuvwxyz\x61\xF1\x80\x80\xE1\x80\xC2\x62\x80\x63\x80\xBF\x64".fix_invalid)
</code></pre>
</li>
<li>
<li>
<p>assert_equal("\uFFFD\u3042".encode("UTF-16BE"),</p>
</li>
<li>
<pre><code> "\xD8\x00\x30\x42".force_encoding(Encoding::UTF_16BE).
</code></pre>
</li>
<li>
<pre><code> fix_invalid)
</code></pre>
</li>
<li>
<p>assert_equal("\uFFFD\u3042".encode("UTF-16LE"),</p>
</li>
<li>
<pre><code> "\x00\xD8\x42\x30".force_encoding(Encoding::UTF_16LE).
</code></pre>
</li>
<li>
<pre><code> fix_invalid)
</code></pre>
</li>
<li>
<p>end<br>
end</p>
</li>
</ul>
<p>class TestString2 < TestString<br>
=end</p>
Ruby master - Bug #6577 (Closed): GC中にstack overflowが発生するとSEGVする
https://redmine.ruby-lang.org/issues/6577
2012-06-12T02:18:44Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>GC中にstack overflowが発生すると、例外作成時にrb_new_objするので[BUG]ります。</p>
<p>原因<br>
(1) caller のテストで Fiber を利用するようにした<br>
(2) caller 実行中に GC が発生<br>
(3) GC 中にマシンスタックオーバーフロー(SEGV)が発生<br>
(4) スタックオーバーフローエラーを作成<br>
(5) スタックオーバーフローエラーを作るときに object allocation している<br>
(6) -> [BUG]</p>
<p>対処法:<br>
スタックオーバーフローエラーを投げるときはオブジェクト作らないようにする<br>
対症療法:<br>
caller のテストで Fiber を使わないようにする<br>
対症療法その2:<br>
callerのテストで GC.disable</p>
<p>nariさんがGC で再帰しないようにするなんて構想も先日語っておられましたが。</p>
Ruby master - Bug #6441 (Rejected): IO.pipe on ENFILE
https://redmine.ruby-lang.org/issues/6441
2012-05-16T12:59:05Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>今の Ruby は open(2) などで、errno=ENFILE が発生した場合、<br>
すなわち fd を使いきっている場合には、rb_gc() を呼び、IO オブジェクトを GC して、<br>
fd が解放されないか試み、それでもダメだったら諦めるとしています。</p>
<p>しかし、IO.pipe の場合はこれに失敗することがあります。<br>
これは、lazy sweep が上記の目的のため T_FILE の場合は直ちに sweep することにしている所、<br>
pipe の場合はその例外にあたらないからです。</p>
Ruby master - Feature #6118 (Feedback): Hash#keys_of(values), returns related keys of given values
https://redmine.ruby-lang.org/issues/6118
2012-03-06T17:55:07Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Hash#key(value) の複数版がほしいです。</p>
<p>{a: 1, b: 2, c: 3, d: 1}.key(1)<br>
=> :a<br>
というメソッドはあるのですが、<br>
{a: 1, b: 2, c: 3, d: 1}.keys_of(1)<br>
=> [:a, :d]<br>
というメソッドは現状ありません。</p>
<p>Ruby での実装例は以下のような感じになります。<br>
どうでしょうか。</p>
<p>class Hash<br>
def keys_of(*a)<br>
each_with_object([]) {|(k, v), r| r << k if a.include? v}<br>
end<br>
end</p>
Ruby master - Feature #5959 (Rejected): Addrinfo#inspectname
https://redmine.ruby-lang.org/issues/5959
2012-02-02T17:16:51Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Addrinfo の導入によって、Socket.getaddrinfo での正引き結果がオブジェクト化され、<br>
元のホスト名を inspect で見れるようになってとても便利になったわけですが、<br>
現在この元のホスト名をとりだす API がありません。</p>
<p>ホスト名とIP アドレスをセットで扱うのに、つまり解決済みの名前とアドレスの組を扱うのに Addrinfo って便利なので、<br>
ホスト名を取り出す API が欲しいです。<br>
現在の C での名前、inspectname か hostname あたりでどうでしょう。</p>
Ruby master - Bug #5868 (Closed): make failed on i686-linux from Bitmap Marking GC
https://redmine.ruby-lang.org/issues/5868
2012-01-09T10:54:12Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>i686-linux に置いて、r34225 以降 make に失敗します。</p>
<p><a href="http://c5632.rubyci.org/~chkbuild/ruby-trunk/log/20120109T010103Z.log.html.gz" class="external">http://c5632.rubyci.org/~chkbuild/ruby-trunk/log/20120109T010103Z.log.html.gz</a><br>
<a href="http://u32.rubyci.org/~chkbuild/ruby-trunk/log/20120108T230102Z.log.html.gz" class="external">http://u32.rubyci.org/~chkbuild/ruby-trunk/log/20120108T230102Z.log.html.gz</a><br>
<a href="http://www.rubyist.net/~akr/chkbuild/debian/ruby-trunk/log/20120109T000400Z.log.html.gz" class="external">http://www.rubyist.net/~akr/chkbuild/debian/ruby-trunk/log/20120109T000400Z.log.html.gz</a></p>
Ruby master - Feature #5861 (Rejected): String#version_compare
https://redmine.ruby-lang.org/issues/5861
2012-01-08T07:54:53Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>バージョン番号っぽい文字列を比較するメソッド、String#version_compare を追加しませんか。<br>
"2.6.18".version_compare("2.6.3") #=> 1<br>
などと使います。</p>
<p>詳細な仕様は Gauche の gauche.version モジュールの version-compare 関数の仕様を丸パクリするのが良いと思います。<br>
提案している名前も Gauche そのままです。<br>
<a href="http://practical-scheme.net/gauche/man/gauche-refj_103.html" class="external">http://practical-scheme.net/gauche/man/gauche-refj_103.html</a></p>
<p>それなりにユースケースはある…というか今まさにテストを書いていて、<br>
Linux カーネルのバージョン番号を欲しくなったのですが、いかがでしょうか。</p>
Ruby master - Feature #5820 (Closed): Merge Onigmo to Ruby 2.0
https://redmine.ruby-lang.org/issues/5820
2011-12-29T02:42:18Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Ruby 1.9 では正規表現エンジンや M17N の基盤として Oniguruma を用いています。<br>
これを 2.0 では Oniguruma の改造版である、k-takata さんの Onigmo に置き換えようという話です。<br>
<a href="https://github.com/k-takata/Onigmo/tree/tmp/ruby-2.0.x" class="external">https://github.com/k-takata/Onigmo/tree/tmp/ruby-2.0.x</a></p>
<p>この取り込みによる影響は以下の通りです。</p>
<ul>
<li>100%互換 (既存のテストが全て無修正で通る)</li>
<li>いくつかの新機能 <a href="/issues/5208">[ruby-dev:44410]</a>
<ul>
<li>正規表現<br>
* \K, \R, \X, (?(cond)yes|no), \g<0>, \g<+n>, (?au)<br>
* Perl 5.10互換の名前参照(←Rubyには不要でしょう。)
<ul>
<li>Shift_JIS, EUC-JPで、全角アルファベットなどの大文字小文字同一視検索に対応。</li>
<li>Shift_JIS, EUC-JPで、\p{Han}, \p{Latin}, \p{Greek}, \p{Cyrillic} に対応。</li>
<li>最適化
<ul>
<li>暗黙のアンカーによる最適化を実装。</li>
<li>
<a href="http://redmine.ruby-lang.org/issues/3568" class="external">http://redmine.ruby-lang.org/issues/3568</a> で無効化された最適化を再度有効化。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>現状は POSIX 文字クラスに非互換があり、それが解決されればマージ可能と認識しています。</p>
Ruby master - Bug #5813 (Closed): net/http's EOFError and Keep-Alive
https://redmine.ruby-lang.org/issues/5813
2011-12-27T14:56:52Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p><a href="https://blade.ruby-lang.org/ruby-dev/39421">[ruby-dev:39421]</a> describes exceptions thrown by open-uri, and raise a question why net/http raises EOFError.</p>
<p>net/http sometimes raises EOFError.<br>
I recently find it is because of Keep-Alive.<br>
On HTTP/1.1, connections are Keep-Alive and a Keep-Alive connection has a timeout.<br>
If a client of such connection doesn't send anything after some communication,<br>
server closes the connection because of Keep-Alive timeout,<br>
and the client's connection shall raise EOFError (sometimes it may be ECONNRESET).</p>
<p>HTTP/1.1 says a client should retry a request if the request is idempotent.<br>
<a href="http://tools.ietf.org/html/rfc2616#section-8.1.4" class="external">http://tools.ietf.org/html/rfc2616#section-8.1.4</a><br>
<a href="http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-17#section-6.1.5" class="external">http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-17#section-6.1.5</a><br>
<a href="http://www.studyinghttp.net/connections" class="external">http://www.studyinghttp.net/connections</a><br>
So I attached a patch to such retry to net/http.</p>
<p>FYI, this timeout of Keep-Alive, KeepAliveTimeout, is:<br>
Apache in FreeBSD ports or pkgsrc is 5 seconds,<br>
the on in Debian Packages or RPM is 15 seconds.</p>
<p>diff --git a/lib/net/http.rb b/lib/net/http.rb<br>
index 879cfe0..13bd1a7 100644<br>
--- a/lib/net/http.rb<br>
+++ b/lib/net/http.rb<br>
@@ -1332,7 +1332,10 @@ module Net #:nodoc:<br>
res<br>
end</p>
<ul>
<li>IDEMPOTENT_METHODS_ = %w/GET HEAD PUT DELETE OPTIONS TRACE/ # :nodoc:</li>
<li>def transport_request(req)</li>
<li>
<pre><code> count = 0
begin_transport req
res = catch(:response) {
req.exec @socket, @curr_http_version, edit_path(req.path)
</code></pre>
</li>
</ul>
<p>@@ -1346,6 +1349,16 @@ module Net #:nodoc:<br>
}<br>
end_transport req, res<br>
res</p>
<ul>
<li>rescue EOFError, Errno::ECONNRESET => exception</li>
<li>
<pre><code> if count == 0 && IDEMPOTENT_METHODS_.include?(req.method)
</code></pre>
</li>
<li>
<pre><code> count += 1
</code></pre>
</li>
<li>
<pre><code> @socket.close if @socket and not @socket.closed?
</code></pre>
</li>
<li>
<pre><code> D "Conn close because of error #{exception}, and retry"
</code></pre>
</li>
<li>
<pre><code> retry
</code></pre>
</li>
<li>
<pre><code> end
</code></pre>
</li>
<li>
<pre><code> D "Conn close because of error #{exception}"
</code></pre>
</li>
<li>
<pre><code> @socket.close if @socket and not @socket.closed?
</code></pre>
</li>
<li>
<pre><code> raise
</code></pre>
rescue => exception<br>
D "Conn close because of error #{exception}"<br>
@socket.close if @socket and not @socket.closed?<br>
diff --git a/test/net/http/test_http.rb b/test/net/http/test_http.rb<br>
index 1515854..2e7ab4e 100644<br>
--- a/test/net/http/test_http.rb<br>
+++ b/test/net/http/test_http.rb<br>
@@ -564,3 +564,29 @@ class TestNetHTTPContinue < Test::Unit::TestCase<br>
assert_not_match(/HTTP/1.1 100 continue/, @debug.string)<br>
end<br>
end</li>
<li>
</ul>
<p>+class TestNetHTTPKeepAlive < Test::Unit::TestCase</p>
<ul>
<li>CONFIG = {</li>
<li>'host' => '127.0.0.1',</li>
<li>'port' => 10081,</li>
<li>'proxy_host' => nil,</li>
<li>'proxy_port' => nil,</li>
<li>'RequestTimeout' => 0.1,</li>
<li>}</li>
<li>
<li>include TestNetHTTPUtils</li>
<li>
<li>def test_keep_alive_get</li>
<li>start {|http|</li>
<li>
<pre><code> res = http.get('/')
</code></pre>
</li>
<li>
<pre><code> assert_kind_of Net::HTTPResponse, res
</code></pre>
</li>
<li>
<pre><code> assert_kind_of String, res.body
</code></pre>
</li>
<li>
<pre><code> sleep 1
</code></pre>
</li>
<li>
<pre><code> assert_nothing_raised {
</code></pre>
</li>
<li>
<pre><code> res = http.get('/')
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> assert_kind_of Net::HTTPResponse, res
</code></pre>
</li>
<li>
<pre><code> assert_kind_of String, res.body
</code></pre>
</li>
<li>}</li>
<li>end<br>
+end<br>
diff --git a/test/net/http/utils.rb b/test/net/http/utils.rb<br>
index 50f616f..07e0b9f 100644<br>
--- a/test/net/http/utils.rb<br>
+++ b/test/net/http/utils.rb<br>
@@ -51,6 +51,7 @@ module TestNetHTTPUtils<br>
:ServerType => Thread,<br>
}<br>
server_config[:OutputBufferSize] = 4 if config('chunked')</li>
<li>server_config[:RequestTimeout] = config('RequestTimeout') if config('RequestTimeout')<br>
if defined?(OpenSSL) and config('ssl_enable')<br>
server_config.update({<br>
:SSLEnable => true,</li>
</ul>
Ruby master - Bug #5768 (Closed): TestRequire#test_race_exceptionで競合するケースがまだある
https://redmine.ruby-lang.org/issues/5768
2011-12-17T10:48:22Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>まだrequireで競合するケースが残っています。<br>
現在のテストだと確率的にしか起きませんが、以下の通り変更すると確実に起きるようになります。</p>
<p>diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb<br>
index 9186a6f..262a5ef 100644<br>
--- a/test/ruby/test_require.rb<br>
+++ b/test/ruby/test_require.rb<br>
@@ -352,7 +352,7 @@ class TestRequire < Test::Unit::TestCase<br>
TestRequire.scratch << :pre<br>
Thread.pass until t2 = TestRequire.scratch[1]<br>
Thread.pass until t2.stop?<br>
-open(<strong>FILE</strong>, "w") {|f| f.puts "TestRequire.scratch << :post"}<br>
+open(<strong>FILE</strong>, "w") {|f| f.puts "TestRequire.scratch << :post"; f.puts "t1,t2=TestRequire.scratch[1, 2];if Thread.current == t2; Thread.pass until t1.stopped?; end"}<br>
raise "con1"<br>
EOS<br>
tmp.close<br>
@@ -364,6 +364,7 @@ raise "con1"<br>
t2_res = nil</p>
<pre><code> t1 = Thread.new do
</code></pre>
<ul>
<li>
<pre><code> scratch << t1
begin
require(path)
rescue RuntimeError
</code></pre>
</li>
</ul>
<p>@@ -389,8 +390,8 @@ raise "con1"<br>
assert_nothing_raised(ThreadError, bug5754) {t1.join}<br>
assert_nothing_raised(ThreadError, bug5754) {t2.join}</p>
<ul>
<li>assert_equal(true, (t1_res ^ t2_res), bug5754)</li>
<li>assert_equal([:pre, t2, :post, :t2, :t1], scratch, bug5754)</li>
</ul>
<ul>
<li>assert_equal(true, (t1_res ^ t2_res), bug5754 + " t1:#{t1_res} t2:#{t2_res}")</li>
<li>assert_equal([:pre, t1, t2, :post, :t2, :t1], scratch, bug5754)<br>
ensure<br>
tmp.close(true) if tmp<br>
end</li>
</ul>
Backport193 - Backport #5757 (Closed): main threadがreadやselectで待っていると、^C でなかなか死なない
https://redmine.ruby-lang.org/issues/5757
2011-12-13T16:35:41Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>FreeBSD 9 にて、 ./ruby と起動して ^C を投げてもなかなか死にません。<br>
./miniruby でも -e'$stdin.read' でも同じです。</p>
<p>仕組みとしては、main thread が read や select で待つ場合、最近は blocking region で<br>
unblock.func に ubf_select を設定するわけですが、この時にシグナルが来ると、</p>
<ol>
<li>どこかのスレッドの sighandler が呼ばれて、rb_thread_wakeup_timer_thread() が呼ばれる</li>
<li>タイマースレッドが起きて、thread_timer() -> timer_thread_function() -> rb_threadptr_check_signal() -> rb_threadptr_interrupt() -> (th->unblock.func)(th->unblock.arg) -> ubf_select() -> rb_thread_wakeup_timer_thread() が呼ばれる</li>
<li>タイマースレッドが起きて、thread_timer() -> timer_thread_function() -> rb_threadptr_check_signal() -> rb_threadptr_interrupt() -> (th->unblock.func)(th->unblock.arg) -> ubf_select() -> rb_thread_wakeup_timer_thread() が呼ばれる</li>
<li>タイマースレッドが起きて、thread_timer() -> timer_thread_function() -> rb_threadptr_check_signal() -> rb_threadptr_interrupt() -> (th->unblock.func)(th->unblock.arg) -> ubf_select() -> rb_thread_wakeup_timer_thread() が呼ばれる<br>
...</li>
</ol>
<p>対策はいくつかあり得ると思うのですが、例えば、ubf_select() から rb_thread_wakeup_timer_thread() を呼ばないようにするとか</p>
Ruby master - Bug #5548 (Closed): OpenSSL::Engine can't load some old engines/new engines
https://redmine.ruby-lang.org/issues/5548
2011-11-02T11:20:11Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Current ext/openssl is missing a check for ENGINE_load_dynamic(),<br>
and doesn't have checks/functions for new engines.</p>
<p>diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb<br>
index 8d8cee3..8f13121 100644<br>
--- a/ext/openssl/extconf.rb<br>
+++ b/ext/openssl/extconf.rb<br>
@@ -118,6 +118,8 @@ if have_header("openssl/engine.h")<br>
have_func("ENGINE_get_digest")<br>
have_func("ENGINE_get_cipher")<br>
have_func("ENGINE_cleanup")<br>
+</p>
<ul>
<li>have_func("ENGINE_load_dynamic")<br>
have_func("ENGINE_load_4758cca")<br>
have_func("ENGINE_load_aep")<br>
have_func("ENGINE_load_atalla")<br>
@@ -126,6 +128,12 @@ if have_header("openssl/engine.h")<br>
have_func("ENGINE_load_nuron")<br>
have_func("ENGINE_load_sureware")<br>
have_func("ENGINE_load_ubsec")</li>
<li>have_func("ENGINE_load_padlock")</li>
<li>have_func("ENGINE_load_capi")</li>
<li>have_func("ENGINE_load_gmp")</li>
<li>have_func("ENGINE_load_gost")</li>
<li>have_func("ENGINE_load_cryptodev")</li>
<li>have_func("ENGINE_load_aesni")<br>
end<br>
have_func("DH_generate_parameters_ex")<br>
have_func("DSA_generate_parameters_ex")<br>
diff --git a/ext/openssl/ossl_engine.c b/ext/openssl/ossl_engine.c<br>
index 79f51b8..829680c 100644<br>
--- a/ext/openssl/ossl_engine.c<br>
+++ b/ext/openssl/ossl_engine.c<br>
@@ -64,29 +64,47 @@ ossl_engine_s_load(int argc, VALUE *argv, VALUE klass)<br>
#if HAVE_ENGINE_LOAD_DYNAMIC<br>
OSSL_ENGINE_LOAD_IF_MATCH(dynamic);<br>
#endif<br>
-#if HAVE_ENGINE_LOAD_CSWIFT</li>
</ul>
<ul>
<li>OSSL_ENGINE_LOAD_IF_MATCH(cswift);<br>
+#if HAVE_ENGINE_LOAD_4758CCA</li>
</ul>
<ul>
<li>OSSL_ENGINE_LOAD_IF_MATCH(4758cca);<br>
#endif<br>
-#if HAVE_ENGINE_LOAD_CHIL</li>
</ul>
<ul>
<li>OSSL_ENGINE_LOAD_IF_MATCH(chil);<br>
+#if HAVE_ENGINE_LOAD_AEP</li>
</ul>
<ul>
<li>OSSL_ENGINE_LOAD_IF_MATCH(aep);<br>
#endif<br>
#if HAVE_ENGINE_LOAD_ATALLA<br>
OSSL_ENGINE_LOAD_IF_MATCH(atalla);<br>
#endif<br>
+#if HAVE_ENGINE_LOAD_CHIL</li>
<li>OSSL_ENGINE_LOAD_IF_MATCH(chil);<br>
+#endif<br>
+#if HAVE_ENGINE_LOAD_CSWIFT</li>
<li>OSSL_ENGINE_LOAD_IF_MATCH(cswift);<br>
+#endif<br>
#if HAVE_ENGINE_LOAD_NURON<br>
OSSL_ENGINE_LOAD_IF_MATCH(nuron);<br>
#endif<br>
+#if HAVE_ENGINE_LOAD_SUREWARE</li>
<li>OSSL_ENGINE_LOAD_IF_MATCH(sureware);<br>
+#endif<br>
#if HAVE_ENGINE_LOAD_UBSEC<br>
OSSL_ENGINE_LOAD_IF_MATCH(ubsec);<br>
#endif<br>
-#if HAVE_ENGINE_LOAD_AEP</li>
</ul>
<ul>
<li>OSSL_ENGINE_LOAD_IF_MATCH(aep);<br>
+#if HAVE_ENGINE_LOAD_PADLOCK</li>
</ul>
<ul>
<li>OSSL_ENGINE_LOAD_IF_MATCH(padlock);<br>
#endif<br>
-#if HAVE_ENGINE_LOAD_SUREWARE</li>
</ul>
<ul>
<li>OSSL_ENGINE_LOAD_IF_MATCH(sureware);<br>
+#if HAVE_ENGINE_LOAD_CAPI</li>
</ul>
<ul>
<li>OSSL_ENGINE_LOAD_IF_MATCH(capi);<br>
#endif<br>
-#if HAVE_ENGINE_LOAD_4758CCA</li>
</ul>
<ul>
<li>OSSL_ENGINE_LOAD_IF_MATCH(4758cca);<br>
+#if HAVE_ENGINE_LOAD_GMP</li>
</ul>
<ul>
<li>OSSL_ENGINE_LOAD_IF_MATCH(gmp);<br>
+#endif<br>
+#if HAVE_ENGINE_LOAD_GOST</li>
<li>OSSL_ENGINE_LOAD_IF_MATCH(gost);<br>
+#endif<br>
+#if HAVE_ENGINE_LOAD_CRYPTODEV</li>
<li>OSSL_ENGINE_LOAD_IF_MATCH(cryptodev);<br>
+#endif<br>
+#if HAVE_ENGINE_LOAD_AESNI</li>
<li>OSSL_ENGINE_LOAD_IF_MATCH(aesni);<br>
#endif<br>
#endif<br>
#ifdef HAVE_ENGINE_LOAD_OPENBSD_DEV_CRYPTO</li>
</ul>
Ruby master - Bug #5547 (Closed): Cleanup engine after a test
https://redmine.ruby-lang.org/issues/5547
2011-11-02T11:16:21Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>OpenSSL::Engine.load() loads engines and register them, and it may change the behavior of some existing methods.</p>
<p>For example on NetBSD 6 with cryptodev, it effects DH as folloing:<br>
./ruby -ropenssl -e'p OpenSSL::PKey::DH.new(256).public_key.private?;p OpenSSL::Engine.load;p OpenSSL::PKey::DH.new(256).public_key.private?'<br>
false<br>
true<br>
true</p>
<p>After loads cryptodev and register it (yes, it needs register. current ext/openssl can't register a engine),<br>
OpenSSL::PKey::DH#private?'s behavior seems to be changed.</p>
<p>Whether it is a bug or not, test/openssl/test_engine.rb should be fixed.</p>
<a name="Index-testopenssltest_enginerb"></a>
<h1 >Index: test/openssl/test_engine.rb<a href="#Index-testopenssltest_enginerb" class="wiki-anchor">¶</a></h1>
<p>--- test/openssl/test_engine.rb (revision 33605)<br>
+++ test/openssl/test_engine.rb (working copy)<br>
@@ -8,6 +8,7 @@<br>
OpenSSL::Engine.load<br>
OpenSSL::Engine.engines<br>
OpenSSL::Engine.engines</p>
<ul>
<li>OpenSSL::Engine.cleanup<br>
end</li>
</ul>
<p>end</p>
Ruby master - Bug #5526 (Closed): SEGV: ./ruby -rfiber -ve'f=Fiber.new{f.resume};f.transfer'
https://redmine.ruby-lang.org/issues/5526
2011-11-01T00:02:47Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>FreeBSD 9 にて、./ruby -rfiber -ve'f=Fiber.new{f.resume};f.transfer' で SEGV します。<br>
他のプラットフォームでも dead fiber call 例外なのはおかしくて、<br>
double resume 例外になるべきでしょう。</p>
Ruby master - Bug #5524 (Closed): IO.wait_for_single_fd(closed fd) sticks on other than Linux
https://redmine.ruby-lang.org/issues/5524
2011-10-31T21:31:41Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>r31428 で、test_wait_for_invalid_fd ってテストを追加しており、<br>
IO.wait_for_single_fd(close 済みの fd) が EBADF になることを確認しているのですが、<br>
これ単体で動かすと FreeBSD で戻ってきません。</p>
<p>思うに、このテストって本来ポータブルに刺さる物なんじゃないでしょうか。<br>
test-allだと何かの弾みで通ってしまうだけで。</p>
<p>% cat poll.c<br>
#include <stdio.h><br>
#include <stdlib.h><br>
#include <poll.h><br>
#include <errno.h><br>
int<br>
main(void) {<br>
int pipes[2];<br>
int res = pipe(pipes);<br>
if (res != 0) abort();<br>
int r = pipes[0];<br>
int w = pipes[1];<br>
res = close(w);<br>
if (res != 0) abort();</p>
<pre><code>struct pollfd fds;
fds.fd = w;
fds.events = POLLOUT;
errno = 0;
res = poll(&fds, 1, 1000);
fprintf(stderr, "%d %d %d\n", res, errno, fds.revents);
return 0;
</code></pre>
<p>}</p>
<p>というプログラムではポータブルに POLLVAL が返り、</p>
<p>#include <stdio.h><br>
#include <stdlib.h><br>
#include <sys/select.h><br>
int<br>
main(void) {<br>
int pipes[2];<br>
int res = pipe(pipes);<br>
if (res != 0) abort();<br>
int r = pipes[0];<br>
int w = pipes[1];<br>
res = close(w);<br>
if (res != 0) abort();<br>
fd_set readfds; FD_ZERO(&readfds);<br>
fd_set writefds; FD_ZERO(&writefds);<br>
fd_set exceptfds; FD_ZERO(&exceptfds);<br>
//struct timeval *timeout = NULL;<br>
//FD_SET(r, &readfds);<br>
FD_SET(w, &writefds);<br>
res = select(1, &readfds, &writefds, &exceptfds, NULL);<br>
return 0;<br>
}</p>
<p>はポータブルにブロックされるあたり、このテストってLinux依存なんじゃ無いかという疑惑を持っているんですがどうでしょう。</p>
Backport193 - Backport #5276 (Closed): 4294967295.8.round is 4294967295 on 32bit
https://redmine.ruby-lang.org/issues/5276
2011-09-05T18:01:46Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>ruby -e'p 4294967295.8.round' must be 4294967296 but 4294967295 on 32bit environment.</p>
Ruby master - Feature #5180 (Closed): net/http の接続時に用いる IP アドレスの指定
https://redmine.ruby-lang.org/issues/5180
2011-08-10T11:45:57Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>通常 net/http を使う時は、Net::HTTP.start("ruby-lang.org") などとホスト名を使います。<br>
で、Socket がホスト名から IP アドレスを引いて、コネクションが張られます。<br>
普通の人はこれで足りるわけですが、ふつうな人はしばしば DNS で引けない IP アドレスに接続したくなります。<br>
例えば、ホスト名は "ruby-lang.org" としたいが、IP アドレスは 127.0.0.1 とか。</p>
<p>以下のパッチをあてると、<br>
Net::HTTP.start("ruby-lang.org", ipaddr: '127.0.0.1')<br>
などとできるようになります。</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/lib/net/http.rb b/lib/net/http.rb
index 7b9ec4f..6d034e0 100644
</span><span class="gd">--- a/lib/net/http.rb
</span><span class="gi">+++ b/lib/net/http.rb
</span><span class="p">@@ -524,7 +524,7 @@</span> module Net #:nodoc:
# _opt_ :: optional hash
#
# _opt_ sets following values by its accessor.
<span class="gd">- # The keys are ca_file, ca_path, cert, cert_store, ciphers,
</span><span class="gi">+ # The keys are ipaddr, ca_file, ca_path, cert, cert_store, ciphers,
</span> # close_on_empty_response, key, open_timeout, read_timeout, ssl_timeout,
# ssl_version, use_ssl, verify_callback, verify_depth and verify_mode.
# If you set :use_ssl as true, you can use https and default value of
<span class="p">@@ -542,6 +542,7 @@</span> module Net #:nodoc:
port, p_addr, p_port, p_user, p_pass = *arg
port = https_default_port if !port && opt && opt[:use_ssl]
http = new(address, port, p_addr, p_port, p_user, p_pass)
<span class="gi">+ http.ipaddr = opt[:ipaddr] if opt[:ipaddr]
</span>
if opt
if opt[:use_ssl]
<span class="p">@@ -575,6 +576,7 @@</span> module Net #:nodoc:
def initialize(address, port = nil)
@address = address
@port = (port || HTTP.default_port)
<span class="gi">+ @ipaddr = nil
</span> @curr_http_version = HTTPVersion
@no_keepalive_server = false
@close_on_empty_response = false
<span class="p">@@ -620,6 +622,17 @@</span> module Net #:nodoc:
# The port number to connect to.
attr_reader :port
<span class="gi">+ # The IP address to connect to/used to connect to
+ def ipaddr
+ started? ? @socket.io.peeraddr[3] : @ipaddr
+ end
+
+ # Set the IP address to connect to
+ def ipaddr=(addr)
+ raise IOError, "ipaddr value changed, but session already started" if started?
+ @ipaddr = addr
+ end
+
</span> # Number of seconds to wait for the connection to open. Any number
# may be used, including Floats for fractional seconds. If the HTTP
# object cannot open a connection in this many seconds, it raises a
<span class="p">@@ -945,7 +958,7 @@</span> module Net #:nodoc:
# without proxy
def conn_address
<span class="gd">- address()
</span><span class="gi">+ @ipaddr || address()
</span> end
def conn_port
</code></pre>
Backport193 - Backport #5130 (Closed): Thread.pass sticks on OpenBSD
https://redmine.ruby-lang.org/issues/5130
2011-08-01T15:51:28Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
On OpenBSD 4.9, following script will stick.</p>
<p>./miniruby -ve'Thread.new{Thread.pass}'<br>
=end</p>
Ruby master - Bug #5114 (Closed): rake's tests imply the binary name of ruby
https://redmine.ruby-lang.org/issues/5114
2011-07-29T16:21:42Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>As Jeremy reported on <a href="/issues/5097">[ruby-core:38530]</a>, current rake tests imply the binary name of ruby as "ruby".<br>
They should use /#{Regexp.quote(RUBY)} -e/ as znz says on <a href="https://blade.ruby-lang.org/ruby-core/38579">[ruby-core:38579]</a>.</p>
Ruby master - Feature #5097 (Closed): Supported platforms of Ruby 1.9.3
https://redmine.ruby-lang.org/issues/5097
2011-07-26T11:52:57Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Let's decide the supported platforms.</p>
<p>== Background</p>
<p><a href="http://redmine.ruby-lang.org/projects/ruby-19/wiki/SupportedPlatforms" class="external">http://redmine.ruby-lang.org/projects/ruby-19/wiki/SupportedPlatforms</a></p>
<p>== Process</p>
<p>If you want to support a platform, please declare.<br>
But when a platform dependent bug is reported, it will be assigned to you.</p>
<p>== Current Maintainer</p>
<p>mswin32, mswin64 (Microsoft Windows):<br>
NAKAMURA Usaku (usa)<br>
mingw32 (Minimalist GNU for Windows):<br>
Nobuyoshi Nakada (nobu)<br>
IA-64 (Debian GNU/Linux):<br>
TAKANO Mitsuhiro (takano32)<br>
Symbian OS:<br>
Alexander Zavorine (azov)<br>
AIX:<br>
Yutaka Kanemoto (kanemoto)<br>
FreeBSD:<br>
Akinori MUSHA (knu)<br>
Solaris:<br>
Naohisa Goto<br>
RHEL, CentOS<br>
KOSAKI Motohiro</p>
<p>Platforms which doesn't have a maintainer are following:</p>
<ul>
<li>Debian</li>
<li>Ubuntu</li>
<li>Mac OS X (LLVM related issues)</li>
<li>cygwin (don't work)</li>
<li>NetBSD (works)</li>
<li>OpenBSD (it may not work)</li>
<li>DragonFlyBSD (don't work)</li>
</ul>
Ruby master - Bug #5094 (Closed): Supported platforms of Ruby 1.9.3
https://redmine.ruby-lang.org/issues/5094
2011-07-26T00:15:52Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>はい、リリース前恒例! サポートプラットフォーム決めのお時間がやって参りました。</p>
<p>前回は 1.9.1 リリース時だったわけですが、あれからずいぶんと経ったので、<br>
改めてサポートするプラットフォームを決めましょう。</p>
<p>== これまでのあらすじ</p>
<p><a href="http://redmine.ruby-lang.org/projects/ruby-19/wiki/SupportedPlatformsJa" class="external">http://redmine.ruby-lang.org/projects/ruby-19/wiki/SupportedPlatformsJa</a></p>
<p>== 決め方</p>
<p>サポートしたいプラットフォームがある方は宣言してください。<br>
ただし、当該プラットフォーム固有っぽいバグがあった場合、そのチケットをアサインする事があるので、<br>
覚悟を決めてから宣言してください。</p>
<p>いつでも「サポート終了!」は宣言できるので [要出典] お気軽にご応募くださいませ。</p>
<p>なお、1.9.3 のリリースのちょっと前あたりで一度締めとする予定です。</p>
<p>== 成瀬の提案</p>
<p>さて、前回のサポートプラットフォーム決めでいくつか反省があるので、ここに一つ提案を行います。</p>
<blockquote>
<p>なお、「メンテナがいる」とは明確なプラットフォームメンテナがいるもの(mswin32など)のほかに、「日々その環境でRubyを開発しているコミッタがいるもの」を含む。</p>
</blockquote>
<p>この後半を削ることを提案します。<br>
例として、Debian はいまだに lenny 32bit が対象になってしまっています。<br>
ようするに切るタイミングが決まらなかったという話で、<br>
こういうのはえいやで決める人がいるべきだろうと思うわけです。</p>
<p>== 現在のメンテナ</p>
<p>ちなみに現在のメンテナは以下の通りです。</p>
<p>mswin32, mswin64 (Microsoft Windows):<br>
NAKAMURA Usaku (usa)<br>
mingw32 (Minimalist GNU for Windows):<br>
Nobuyoshi Nakada (nobu)<br>
IA-64 (Debian GNU/Linux):<br>
TAKANO Mitsuhiro (takano32)<br>
Symbian OS:<br>
Alexander Zavorine (azov)<br>
AIX:<br>
Yutaka Kanemoto (kanemoto)<br>
FreeBSD:<br>
Akinori MUSHA (knu)<br>
Solaris:<br>
Naohisa Goto</p>
<p>逆にメンテナがいない主なプラットフォーム(と備考)は以下の通りです。</p>
<ul>
<li>Debian</li>
<li>Ubuntu</li>
<li>CentOS</li>
<li>Mac OS X (LLVM絡みが微妙)</li>
<li>cygwin (動かない)</li>
<li>NetBSD (動く)</li>
<li>OpenBSD (動かない気がする)</li>
<li>DragonFlyBSD (動かない)</li>
</ul>
Backport192 - Backport #5075 (Rejected): invalid *fdp in Mac OS X and FreeBSD over recvmsg with S...
https://redmine.ruby-lang.org/issues/5075
2011-07-22T17:51:06Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Mac OS X と FreeBSD にて、存在しない fd を close してしまう問題について、<br>
現在 r32598 で応急処置が施されていますが、根本的な原因について、<br>
sys/kern/uipc_socket.c を見るに、<br>
<a href="http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/kern/uipc_socket.c?rev=1.340.2.6.2.1;content-type=text%2Fplain;only_with_tag=RELENG_8_2_0_RELEASE" class="external">http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/kern/uipc_socket.c?rev=1.340.2.6.2.1;content-type=text%2Fplain;only_with_tag=RELENG_8_2_0_RELEASE</a></p>
<pre><code> * Process one or more MT_CONTROL mbufs present before any data mbufs
* in the first mbuf chain on the socket buffer. If MSG_PEEK, we
* just copy the data; if !MSG_PEEK, we call into the protocol to
* perform externalization (or freeing if controlp == NULL).
</code></pre>
<p>とあるので、recvmsg に MSG_PEEK を与えた場合は invalid なものが返ってくると思うのですが。</p>
<p>ちなみに、以下のような printf パッチをあてて走らせると、discard_cmsg() に来たものは全て invalid になっています。</p>
<p>diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c<br>
index 61e0576..ad44fb4 100644<br>
--- a/ext/socket/ancdata.c<br>
+++ b/ext/socket/ancdata.c<br>
@@ -1379,6 +1379,7 @@ rb_recvmsg(int fd, struct msghdr *msg, int flags)<br>
static void<br>
discard_cmsg(struct cmsghdr *cmh, char *msg_end)<br>
{</p>
<ul>
<li>fprintf(stderr, "discard_cmsg-begin\n");<br>
if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {<br>
int *fdp = (int *)CMSG_DATA(cmh);<br>
int *end = (int *)((char *)cmh + cmh->cmsg_len);<br>
@@ -1391,12 +1392,18 @@ discard_cmsg(struct cmsghdr *cmh, char *msg_end)<br>
*/<br>
struct stat buf;<br>
if (fstat(*fdp, &buf) == 0) {</li>
<li>
<pre><code> fprintf(stderr, "fdp: %d is valid (%p %p %p)\n", *fdp,fdp,end,msg_end);
rb_update_max_fd(*fdp);
close(*fdp);
}
</code></pre>
</li>
<li>
<pre><code> else {
</code></pre>
</li>
<li>
<pre><code> fprintf(stderr, "fdp: %d is invalid (%p %p %p)\n", *fdp,fdp,end,msg_end);
</code></pre>
</li>
<li>
<pre><code> rb_backtrace();
</code></pre>
</li>
<li>
<pre><code> }
fdp++;
}
</code></pre>
}</li>
<li>fprintf(stderr, "discard_cmsg-end\n");<br>
}<br>
#endif</li>
</ul>
<p>@@ -1432,6 +1439,7 @@ make_io_for_unix_rights(VALUE ctl, struct cmsghdr *cmh, char *msg_end)<br>
(char *)fdp + sizeof(int) <= msg_end) {<br>
int fd = *fdp;<br>
struct stat stbuf;</p>
<ul>
<li>fprintf(stderr,"makeiounixr: %d (%p %p %p)\n", *fdp,fdp,end,msg_end);<br>
VALUE io;<br>
if (fstat(fd, &stbuf) == -1)<br>
rb_raise(rb_eSocket, "invalid fd in SCM_RIGHTS");</li>
</ul>
Ruby master - Bug #5026 (Closed): 1.9.3 allows URI(uri, parser)
https://redmine.ruby-lang.org/issues/5026
2011-07-14T07:28:08Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>r28699 introduces a new API: the second argument of URI(uri [, parser]).<br>
But I object this because such parser argument should be obsolete.</p>
Ruby master - Feature #4921 (Rejected): Remove intern.h
https://redmine.ruby-lang.org/issues/4921
2011-06-23T08:15:07Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>まず、intern.h って何者なんでしょう。<br>
推測としては internal の意だと思うんですが、その場合 include/ruby にいるのは<br>
よろしくないですし、一方で公開 API っぽいのが名実ともに多い気がします。</p>
<p>思うに 1.9 において、intern.h の中身は include/ruby/ruby.h か、<br>
最近新設された internal.h のどちらかにあるべきで、include/ruby/intern.h は<br>
もう必要ないのではないでしょうか。</p>
Ruby master - Bug #4886 (Closed): autoload in instance_eval doesn't work
https://redmine.ruby-lang.org/issues/4886
2011-06-15T09:53:15Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>autoload を instance_eval の中で使うとうまく動きません。</p>
<p>% ./ruby -e'instance_eval{autoload :R,"a";p R}'<br>
-e:1:in <code>block in <main>': uninitialized constant R (NameError) from -e:1:in </code>instance_eval'<br>
from -e:1:in `'</p>
Ruby master - Bug #4825 (Closed): BigDecimal#new is broken
https://redmine.ruby-lang.org/issues/4825
2011-06-04T21:32:58Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>RubySpec にて以下のテストが失敗しています。</p>
<p>BigDecimal.new creates a new object of class BigDecimal FAILED<br>
Expected #<a href="BigDecimal:445ef968,'0.1E0',9(18)" class="external">BigDecimal:445ef968,'0.1E0',9(18)</a><br>
to equal (1/10)</p>
<p>/usr/home/chkbuild/build/ruby-trunk/20110604T110102Z/rubyspec/library/bigdecimal/new_spec.rb:12:in <code>block (3 levels) in <top (required)>' /usr/home/chkbuild/build/ruby-trunk/20110604T110102Z/rubyspec/library/bigdecimal/new_spec.rb:8:in </code>each'<br>
/usr/home/chkbuild/build/ruby-trunk/20110604T110102Z/rubyspec/library/bigdecimal/new_spec.rb:8:in <code>block (2 levels) in <top (required)>' /usr/home/chkbuild/build/ruby-trunk/20110604T110102Z/rubyspec/library/bigdecimal/new_spec.rb:4:in </code><top (required)>'</p>
Ruby master - Feature #4595 (Closed): TkPhotoImage documentation
https://redmine.ruby-lang.org/issues/4595
2011-04-22T12:12:22Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
以下のような pull request が来ています。</p>
<p>I have documented some method from TkPhotoImage, based on the original Tcl/Tk docs.</p>
<p><a href="https://github.com/ruby/ruby/pull/9" class="external">https://github.com/ruby/ruby/pull/9</a><br>
=end</p>
Ruby master - Bug #4455 (Closed): rubygem's test fails when source directory and build directory ...
https://redmine.ruby-lang.org/issues/4455
2011-03-01T23:12:35Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
In lib/rubygems/test_case.rb, it sets @project_dir as Dir.pwd.<br>
But the use cases of @project_dir are both top of source and build directory.<br>
It breaks when they differ.</p>
<p>This happens when:</p>
<p>cd $HOME<br>
mkdir bin-ruby<br>
svn co <a href="http://svn.ruby-lang.org/repos/ruby/trunk" class="external">http://svn.ruby-lang.org/repos/ruby/trunk</a> src-ruby<br>
cd ruby<br>
autoconf<br>
mkdir ../build-ruby<br>
cd ../build-ruby<br>
../ruby/configure --prefix=$HOME/bin-ruby<br>
make<br>
make install<br>
make test-all</p>
<p>The error messages are following:<br>
2) Failure:<br>
test_self_prefix(TestGem) [/home/naruse/ruby/test/rubygems/test_gem.rb:779]:<br>
Expected "/home/naruse/obj/ruby", not "/home/naruse/ruby".</p>
<ol start="3">
<li>
<p>Failure:<br>
test_self_prefix_libdir(TestGem) [/home/naruse/ruby/test/rubygems/test_gem.rb:786]:<br>
Expected "/home/naruse/ruby" to be nil.</p>
</li>
<li>
<p>Failure:<br>
test_self_find_files(TestGem) [/home/naruse/ruby/test/rubygems/test_gem.rb:655]:<br>
Expected ["/home/naruse/obj/ruby/test/rubygems/sff/discover.rb",<br>
"/tmp/test-all/test_rubygems_56936/gemhome/gems/sff-2/lib/sff/discover.rb",<br>
"/tmp/test-all/test_rubygems_56936/gemhome/gems/sff-1/lib/sff/discover.rb"], not ["/home/naruse/ruby/test/rubygems/sff/discover.rb",<br>
"/tmp/test-all/test_rubygems_56936/gemhome/gems/sff-2/lib/sff/discover.rb",<br>
"/tmp/test-all/test_rubygems_56936/gemhome/gems/sff-1/lib/sff/discover.rb"].</p>
</li>
<li>
<p>Failure:<br>
test_self_prefix_sitelibdir(TestGem) [/home/naruse/ruby/test/rubygems/test_gem.rb:795]:<br>
Expected "/home/naruse/ruby" to be nil.</p>
</li>
<li>
<p>Error:<br>
test_execute_removes_executable(TestGemCommandsUninstallCommand):<br>
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.</p>
<p>/home/naruse/obj/ruby/ruby mkrf_conf.rb</p>
</li>
</ol>
<p>rake RUBYARCHDIR=/tmp/test-all/test_rubygems_56936/gemhome/gems/a-2/lib RUBYLIBDIR=/tmp/test-all/test_rubygems_56936/gemhome/gems/a-2/lib<br>
/home/naruse/obj/ruby/rbconfig.rb:7: ruby lib version (1.9.3) doesn't match executable version (1.8.7) (RuntimeError)<br>
from /home/naruse/ruby/lib/rubygems.rb:36:in <code>require' from /home/naruse/ruby/lib/rubygems.rb:36 from /usr/local/bin/rake:9:in </code>require'<br>
from /usr/local/bin/rake:9</p>
<p>Gem files will remain installed in /tmp/test-all/test_rubygems_56936/gemhome/gems/a-2 for inspection.<br>
Results logged to /tmp/test-all/test_rubygems_56936/gemhome/gems/a-2/ext/a/gem_make.out</p>
<pre><code>/home/naruse/ruby/test/rubygems/test_gem_commands_uninstall_command.rb:32:in `block (2 levels) in test_execute_removes_executable'
/home/naruse/ruby/test/rubygems/test_gem_commands_uninstall_command.rb:31:in `block in test_execute_removes_executable'
/home/naruse/ruby/test/rubygems/test_gem_commands_uninstall_command.rb:30:in `test_execute_removes_executable'
../../ruby/test/runner.rb:10:in `<main>'
</code></pre>
<ol start="7">
<li>
<p>Error:<br>
test_execute_prerelease(TestGemCommandsUninstallCommand):<br>
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.</p>
<p>/home/naruse/obj/ruby/ruby mkrf_conf.rb</p>
</li>
</ol>
<p>rake RUBYARCHDIR=/tmp/test-all/test_rubygems_56936/gemhome/gems/pre-2.b/lib RUBYLIBDIR=/tmp/test-all/test_rubygems_56936/gemhome/gems/pre-2.b/lib<br>
/home/naruse/obj/ruby/rbconfig.rb:7: ruby lib version (1.9.3) doesn't match executable version (1.8.7) (RuntimeError)<br>
from /home/naruse/ruby/lib/rubygems.rb:36:in <code>require' from /home/naruse/ruby/lib/rubygems.rb:36 from /usr/local/bin/rake:9:in </code>require'<br>
from /usr/local/bin/rake:9</p>
<p>Gem files will remain installed in /tmp/test-all/test_rubygems_56936/gemhome/gems/pre-2.b for inspection.<br>
Results logged to /tmp/test-all/test_rubygems_56936/gemhome/gems/pre-2.b/ext/a/gem_make.out</p>
<pre><code>/home/naruse/ruby/test/rubygems/test_gem_commands_uninstall_command.rb:100:in `block (2 levels) in test_execute_prerelease'
/home/naruse/ruby/test/rubygems/test_gem_commands_uninstall_command.rb:99:in `block in test_execute_prerelease'
/home/naruse/ruby/test/rubygems/test_gem_commands_uninstall_command.rb:98:in `test_execute_prerelease'
../../ruby/test/runner.rb:10:in `<main>'
</code></pre>
<ol start="8">
<li>Error:<br>
test_class_build(TestGemExtRakeBuilder):<br>
Gem::InstallError: rake failed:</li>
</ol>
<p>/home/naruse/obj/ruby/ruby mkrf_conf.rb</p>
<p>rake RUBYARCHDIR=/tmp/test-all/test_rubygems_56936/prefix RUBYLIBDIR=/tmp/test-all/test_rubygems_56936/prefix<br>
/home/naruse/obj/ruby/rbconfig.rb:7: ruby lib version (1.9.3) doesn't match executable version (1.8.7) (RuntimeError)<br>
from /home/naruse/ruby/lib/rubygems.rb:36:in <code>require' from /home/naruse/ruby/lib/rubygems.rb:36 from /usr/local/bin/rake:9:in </code>require'<br>
from /usr/local/bin/rake:9</p>
<pre><code>/home/naruse/ruby/test/rubygems/test_gem_ext_rake_builder.rb:36:in `block (2 levels) in test_class_build'
/home/naruse/ruby/test/rubygems/test_gem_ext_rake_builder.rb:34:in `chdir'
/home/naruse/ruby/test/rubygems/test_gem_ext_rake_builder.rb:34:in `block in test_class_build'
/home/naruse/ruby/test/rubygems/test_gem_ext_rake_builder.rb:33:in `test_class_build'
../../ruby/test/runner.rb:10:in `<main>'
</code></pre>
<ol start="9">
<li>
<p>Error:<br>
test_install_ignore_dependencies(TestGemInstaller):<br>
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.</p>
<p>/home/naruse/obj/ruby/ruby mkrf_conf.rb --build_arg1 --build_arg2</p>
</li>
</ol>
<p>rake RUBYARCHDIR=/tmp/test-all/test_rubygems_56936/gemhome/gems/a-2/lib RUBYLIBDIR=/tmp/test-all/test_rubygems_56936/gemhome/gems/a-2/lib<br>
/home/naruse/obj/ruby/rbconfig.rb:7: ruby lib version (1.9.3) doesn't match executable version (1.8.7) (RuntimeError)<br>
from /home/naruse/ruby/lib/rubygems.rb:36:in <code>require' from /home/naruse/ruby/lib/rubygems.rb:36 from /usr/local/bin/rake:9:in </code>require'<br>
from /usr/local/bin/rake:9</p>
<p>Gem files will remain installed in /tmp/test-all/test_rubygems_56936/gemhome/gems/a-2 for inspection.<br>
Results logged to /tmp/test-all/test_rubygems_56936/gemhome/gems/a-2/ext/a/gem_make.out</p>
<pre><code>/home/naruse/ruby/test/rubygems/test_gem_installer.rb:698:in `block (2 levels) in test_install_ignore_dependencies'
/home/naruse/ruby/test/rubygems/test_gem_installer.rb:697:in `block in test_install_ignore_dependencies'
/home/naruse/ruby/test/rubygems/test_gem_installer.rb:696:in `test_install_ignore_dependencies'
../../ruby/test/runner.rb:10:in `<main>'
</code></pre>
<ol start="10">
<li>
<p>Error:<br>
test_install_with_no_prior_files(TestGemInstaller):<br>
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.</p>
<p>/home/naruse/obj/ruby/ruby mkrf_conf.rb --build_arg1 --build_arg2</p>
</li>
</ol>
<p>rake RUBYARCHDIR=/tmp/test-all/test_rubygems_56936/gemhome/gems/a-2/lib RUBYLIBDIR=/tmp/test-all/test_rubygems_56936/gemhome/gems/a-2/lib<br>
/home/naruse/obj/ruby/rbconfig.rb:7: ruby lib version (1.9.3) doesn't match executable version (1.8.7) (RuntimeError)<br>
from /home/naruse/ruby/lib/rubygems.rb:36:in <code>require' from /home/naruse/ruby/lib/rubygems.rb:36 from /usr/local/bin/rake:9:in </code>require'<br>
from /usr/local/bin/rake:9</p>
<p>Gem files will remain installed in /tmp/test-all/test_rubygems_56936/gemhome/gems/a-2 for inspection.<br>
Results logged to /tmp/test-all/test_rubygems_56936/gemhome/gems/a-2/ext/a/gem_make.out</p>
<pre><code>/home/naruse/ruby/test/rubygems/test_gem_installer.rb:594:in `block (2 levels) in test_install_with_no_prior_files'
/home/naruse/ruby/test/rubygems/test_gem_installer.rb:593:in `block in test_install_with_no_prior_files'
/home/naruse/ruby/test/rubygems/test_gem_installer.rb:592:in `test_install_with_no_prior_files'
../../ruby/test/runner.rb:10:in `<main>'
</code></pre>
<ol start="11">
<li>
<p>Error:<br>
test_install_check_dependencies_install_dir(TestGemInstaller):<br>
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.</p>
<p>/home/naruse/obj/ruby/ruby mkrf_conf.rb --build_arg1 --build_arg2</p>
</li>
</ol>
<p>rake RUBYARCHDIR=/tmp/test-all/test_rubygems_56936/gemhome2/gems/a-2/lib RUBYLIBDIR=/tmp/test-all/test_rubygems_56936/gemhome2/gems/a-2/lib<br>
/home/naruse/obj/ruby/rbconfig.rb:7: ruby lib version (1.9.3) doesn't match executable version (1.8.7) (RuntimeError)<br>
from /home/naruse/ruby/lib/rubygems.rb:36:in <code>require' from /home/naruse/ruby/lib/rubygems.rb:36 from /usr/local/bin/rake:9:in </code>require'<br>
from /usr/local/bin/rake:9</p>
<p>Gem files will remain installed in /tmp/test-all/test_rubygems_56936/gemhome2/gems/a-2 for inspection.<br>
Results logged to /tmp/test-all/test_rubygems_56936/gemhome2/gems/a-2/ext/a/gem_make.out</p>
<pre><code>/home/naruse/ruby/test/rubygems/test_gem_installer.rb:673:in `block (2 levels) in test_install_check_dependencies_install_dir'
/home/naruse/ruby/test/rubygems/test_gem_installer.rb:672:in `block in test_install_check_dependencies_install_dir'
/home/naruse/ruby/test/rubygems/test_gem_installer.rb:671:in `test_install_check_dependencies_install_dir'
../../ruby/test/runner.rb:10:in `<main>'
</code></pre>
<ol start="12">
<li>
<p>Error:<br>
test_install(TestGemInstaller):<br>
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.</p>
<p>/home/naruse/obj/ruby/ruby mkrf_conf.rb --build_arg1 --build_arg2</p>
</li>
</ol>
<p>rake RUBYARCHDIR=/tmp/test-all/test_rubygems_56936/gemhome/gems/a-2/lib RUBYLIBDIR=/tmp/test-all/test_rubygems_56936/gemhome/gems/a-2/lib<br>
/home/naruse/obj/ruby/rbconfig.rb:7: ruby lib version (1.9.3) doesn't match executable version (1.8.7) (RuntimeError)<br>
from /home/naruse/ruby/lib/rubygems.rb:36:in <code>require' from /home/naruse/ruby/lib/rubygems.rb:36 from /usr/local/bin/rake:9:in </code>require'<br>
from /usr/local/bin/rake:9</p>
<p>Gem files will remain installed in /tmp/test-all/test_rubygems_56936/gemhome/gems/a-2 for inspection.<br>
Results logged to /tmp/test-all/test_rubygems_56936/gemhome/gems/a-2/ext/a/gem_make.out</p>
<pre><code>/home/naruse/ruby/test/rubygems/test_gem_installer.rb:560:in `block (2 levels) in test_install'
/home/naruse/ruby/test/rubygems/test_gem_installer.rb:559:in `block in test_install'
/home/naruse/ruby/test/rubygems/test_gem_installer.rb:558:in `test_install'
../../ruby/test/runner.rb:10:in `<main>'
</code></pre>
<p>=end</p>
Ruby master - Bug #4426 (Closed): rubygems/test_gem_gemcutter_utilities.rb fails
https://redmine.ruby-lang.org/issues/4426
2011-02-22T20:57:18Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
When run make RUBYOPT=-w TESTS='-v rubygems/test_gem_gemcutter_utilities.rb' test-all, it fails as following:</p>
<ol>
<li>
<p>Error:<br>
test_sign_in(TestGemGemcutterUtilities):<br>
NameError: uninitialized constant Gem::Command<br>
/home/naruse/ruby/test/rubygems/test_gem_gemcutter_utilities.rb:19:in `setup'</p>
</li>
<li>
<p>Error:<br>
test_sign_in_skips_with_existing_credentials(TestGemGemcutterUtilities):<br>
NameError: uninitialized constant Gem::Command<br>
/home/naruse/ruby/test/rubygems/test_gem_gemcutter_utilities.rb:19:in `setup'</p>
</li>
<li>
<p>Error:<br>
test_sign_in_with_bad_credentials(TestGemGemcutterUtilities):<br>
NameError: uninitialized constant Gem::Command<br>
/home/naruse/ruby/test/rubygems/test_gem_gemcutter_utilities.rb:19:in `setup'</p>
</li>
<li>
<p>Error:<br>
test_sign_in_with_host(TestGemGemcutterUtilities):<br>
NameError: uninitialized constant Gem::Command<br>
/home/naruse/ruby/test/rubygems/test_gem_gemcutter_utilities.rb:19:in `setup'</p>
</li>
<li>
<p>Error:<br>
test_sign_in_with_other_credentials_doesnt_overwrite_other_keys(TestGemGemcutterUtilities):<br>
NameError: uninitialized constant Gem::Command<br>
/home/naruse/ruby/test/rubygems/test_gem_gemcutter_utilities.rb:19:in `setup'<br>
=end</p>
</li>
</ol>
Ruby master - Bug #4395 (Closed): Can't require test/rubygems/simple_gem when tests run in differ...
https://redmine.ruby-lang.org/issues/4395
2011-02-14T09:34:46Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
It fails as following:</p>
<ol>
<li>
<p>Skipped:<br>
test_require_failed(test/rubygems/simple_gem) [/home/naruse/ruby/test/rubygems/test_gem_format.rb:8]:<br>
cannot load such file -- test/rubygems/simple_gem</p>
</li>
<li>
<p>Skipped:<br>
test_require_failed(test/rubygems/simple_gem) [/home/naruse/ruby/test/rubygems/test_gem_validator.rb:8]:<br>
cannot load such file -- test/rubygems/simple_gem</p>
</li>
</ol>
<p>Line 8 of test/rubygems/test_gem_format.rb should use require_relative.<br>
=end</p>
Ruby master - Bug #4376 (Closed): rdoc can't handle correctly the return value when the file has ...
https://redmine.ruby-lang.org/issues/4376
2011-02-07T13:11:12Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
From r30806 to r30813, make rdoc raises error on LANG=C environment like:<br>
<a href="http://59.106.172.211/~chkbuild/ruby-trunk/log/20110207T010100Z.log.html.gz" class="external">http://59.106.172.211/~chkbuild/ruby-trunk/log/20110207T010100Z.log.html.gz</a></p>
<p>This is because the encoding of output is set to US-ASCII, failed character<br>
encoding conversion on doc/re.rdoc, and wrongly treated nil as String.</p>
<p>The main bug is set to US-ASCII, so I fixed it in r30813.<br>
But nil treatment should be rdoc's bug, so I report this.</p>
<p>Generating RDoc documentation<br>
Parsing sources...<br>
unable to convert U+6771 from UTF-8 to US-ASCII for ../../ruby/doc/re.rdoc, skipping<br>
Before reporting this, could you check that the file you're documenting<br>
has proper syntax:</p>
<p>/home/naruse/local/ruby/bin/ruby -c ../../ruby/re.c</p>
<p>RDoc is not a full Ruby parser and will fail when fed invalid ruby programs.</p>
<p>The internal error was:</p>
<pre><code> (NoMethodError) undefined method `sub' for nil:NilClass
</code></pre>
<p>/home/naruse/ruby/lib/rdoc/markup/pre_process.rb:126:in <code>include_file' /home/naruse/ruby/lib/rdoc/markup/pre_process.rb:76:in </code>block in handle'<br>
/home/naruse/ruby/lib/rdoc/markup/pre_process.rb:61:in <code>gsub!' /home/naruse/ruby/lib/rdoc/markup/pre_process.rb:61:in </code>handle'<br>
/home/naruse/ruby/lib/rdoc/parser/c.rb:867:in <code>look_for_directives_in' /home/naruse/ruby/lib/rdoc/parser/c.rb:516:in </code>find_class_comment'<br>
/home/naruse/ruby/lib/rdoc/parser/c.rb:687:in <code>handle_class_module' /home/naruse/ruby/lib/rdoc/parser/c.rb:204:in </code>block in do_classes'<br>
/home/naruse/ruby/lib/rdoc/parser/c.rb:199:in <code>scan' /home/naruse/ruby/lib/rdoc/parser/c.rb:199:in </code>do_classes'<br>
/home/naruse/ruby/lib/rdoc/parser/c.rb:987:in <code>scan' /home/naruse/ruby/lib/rdoc/rdoc.rb:322:in </code>parse_file'<br>
/home/naruse/ruby/lib/rdoc/rdoc.rb:367:in <code>block in parse_files' /home/naruse/ruby/lib/rdoc/rdoc.rb:365:in </code>map'<br>
/home/naruse/ruby/lib/rdoc/rdoc.rb:365:in <code>parse_files' /home/naruse/ruby/lib/rdoc/rdoc.rb:423:in </code>document'<br>
../../ruby/bin/rdoc:15:in <code><main>' uh-oh! RDoc had a problem: undefined method </code>sub' for nil:NilClass</p>
<p>run with --debug for full backtrace<br>
*** Error code 1</p>
<p>Stop in /home/naruse/obj/ruby.<br>
=end</p>
Backport187 - Backport #4171 (Closed): Warn Array#choice
https://redmine.ruby-lang.org/issues/4171
2010-12-19T18:26:40Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
Array#choice は Ruby 1.8.7 で入ったメソッドですが、1.9 ではなくなっているので、<br>
ruby_1_8 だけでなく、ruby_1_8_7 パッチリリースでも warning を出すようにしませんか。<br>
=end</p>
Ruby master - Bug #4163 (Closed): RubyGems uses deprecated API: YAML.quick_emit.
https://redmine.ruby-lang.org/issues/4163
2010-12-16T04:46:28Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
RubyGems::Specification#to_yaml uses depcrecated API: YAML.quick_emit,<br>
and it show many warnings on make test-all.<br>
/usr/home/chkbuild/build/ruby-trunk//ruby/lib/rubygems/specification.rb:706:in `to_yaml': YAML.quick_emit is deprecated<br>
=end</p>
Ruby master - Feature #3946 (Closed): Array#packのqQ指定子に機種依存サイズフラグ!を追加
https://redmine.ruby-lang.org/issues/3946
2010-10-14T15:36:56Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
Ruby の伏魔殿 Array#pack ですが、機種依存な部分をいじる際にはしばしば強力かつ唯一の手段になる事があります。<br>
具体的には RubySpec 書く時とか。</p>
<p>さて、q/Q は 64bit signed/unsigned int なのですが、機種依存の long long (厳密には LONG_LONG) のサイズが必要な場合、<br>
現状 Ruby レベルから取る手段が一切ありません。<br>
すでに s/S/i/I/l/L (16bit/32bit/32bit) は、! をつけることでその機種の short/int/long のサイズになるため、<br>
これを q/Q に拡張すると唯一の手段が提供される事になります。</p>
<p>というわけで、Array#packのqQ指定子に機種依存サイズフラグ!を追加したいです。<br>
=end</p>
Ruby master - Bug #3816 (Closed): OpenSSL::BN#prime?の引数の取り扱いがおかしい
https://redmine.ruby-lang.org/issues/3816
2010-09-10T16:20:29Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
OpenSSL::BN#prime?を引数なしで呼ぶと以下の通り例外が出ます。</p>
<p>irb(main):001:0> require'openssl'=> trueirb(main):002:0> OpenSSL::BN.new("461166461445805738999").prime?<br>
TypeError: no implicit conversion from nil to integer<br>
from (irb):2:in <code>prime?' from (irb):2 from /home/naruse/local/ruby_1_9_2/bin/irb:12:in </code>'</p>
<p>コードを見るに、rb_scan_args の引数との比較が誤っているように見えるので、引数ありでもおかしいでしょう。<br>
以下の変更で直ります。</p>
<p>diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c<br>
index bec5135..6adc59f 100644<br>
--- a/ext/openssl/ossl_bn.c<br>
+++ b/ext/openssl/ossl_bn.c<br>
@@ -669,7 +669,7 @@ ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)<br>
VALUE vchecks;<br>
int checks = BN_prime_checks;</p>
<ul>
<li>if (rb_scan_args(argc, argv, "01", &vchecks) == 0) {</li>
</ul>
<ul>
<li>if (rb_scan_args(argc, argv, "01", &vchecks) == 1) {<br>
checks = NUM2INT(vchecks);<br>
}<br>
GetBN(self, bn);<br>
=end</li>
</ul>
Ruby master - Bug #3672 (Closed): PTY.getpty with non exist program
https://redmine.ruby-lang.org/issues/3672
2010-08-10T10:48:52Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
存在しないプログラムを指定して PTY.getpty を呼ぶと [BUG] になります。<br>
PTY.getpty 側での対処と rb_fork_err 側での対処がありえますが、<br>
とりあえず後者側でも対処が必要でしょう。</p>
<p>% ./ruby -rpty -e'PTY.getpty"a"'<br>
-e:1: [BUG] rb_sys_fail(fork failed) - errno == 0<br>
ruby 1.9.3dev (2010-08-09 trunk 28938) [x86_64-freebsd8.1]</p>
<h2>-- control frame ----------<br>
c:0004 p:---- s:0010 b:0010 l:000009 d:000009 CFUNC :getpty<br>
c:0003 p:0017 s:0006 b:0006 l:0024b8 d:0010e8 EVAL -e:1<br>
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH<br>
c:0001 p:0000 s:0002 b:0002 l:0024b8 d:0024b8 TOP</h2>
<p>-- Ruby level backtrace information ----------------------------------------<br>
-e:1:in <code><main>' -e:1:in </code>getpty'</p>
<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>zsh: abort (core dumped) ./ruby -rpty -e'PTY.getpty"a"'<br>
=end</p>
Ruby master - Bug #3593 (Closed): cont.cで"PAGE_SIZE" redefined
https://redmine.ruby-lang.org/issues/3593
2010-07-21T17:20:27Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
cont.cで以下のようなwarningがでます。<br>
ifndefを使うべきか、RB_PAGE_SIZEなどと別の名前を使うべきか迷ったので、対処お願いします。<br>
../../ruby/cont.c:45:1: warning: "PAGE_SIZE" redefined<br>
In file included from /usr/include/sys/param.h:110,<br>
from /usr/include/pthread_np.h:34,<br>
from ../../ruby/thread_pthread.h:16,<br>
from ../../ruby/vm_core.h:29,<br>
from ../../ruby/cont.c:13:<br>
/usr/include/machine/param.h:100:1: warning: this is the location of the previous definition<br>
../../ruby/cont.c:46:1: warning: "PAGE_MASK" redefined<br>
/usr/include/machine/param.h:101:1: warning: this is the location of the previous definition<br>
../../ruby/cont.c:45:1: warning: "PAGE_SIZE" redefined<br>
In file included from /usr/include/sys/param.h:111,<br>
from /usr/include/pthread_np.h:35,<br>
from ../../ruby/thread_pthread.h:17,<br>
from ../../ruby/vm_core.h:30,<br>
from ../../ruby/cont.c:14:<br>
/usr/include/machine/param.h:100:1: warning: this is the location of the previous definition<br>
../../ruby/cont.c:46:1: warning: "PAGE_MASK" redefined<br>
/usr/include/machine/param.h:101:1: warning: this is the location of the previous definition<br>
../../ruby/cont.c: In function 'fiber_initialize_machine_stack_context':<br>
../../ruby/cont.c:567: warning: assignment from incompatible pointer type<br>
=end</p>
Ruby master - Bug #3568 (Closed): /(?<=a).*b/ =~ "aab" doesn't match
https://redmine.ruby-lang.org/issues/3568
2010-07-14T12:09:42Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
「1.9.1で /(?<=a).*b/ =~ "aab" がマッチしないのはなぜ? 」<br>
<a href="http://pc12.2ch.net/test/read.cgi/tech/1272248179/735" class="external">http://pc12.2ch.net/test/read.cgi/tech/1272248179/735</a><br>
=end</p>
Ruby master - Bug #3515 (Closed): FreeBSD wrongly raises ECONNRESET on close(2)
https://redmine.ruby-lang.org/issues/3515
2010-07-02T12:20:40Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
FreeBSD 8 では現在以下のようなテストに失敗しています。</p>
<ol>
<li>
<p>Error:<br>
test_idle(IMAPTest):<br>
Errno::ECONNRESET: Connection reset by peer<br>
/home/naruse/ruby/test/net/imap/test_imap.rb:189:in `test_idle'</p>
</li>
<li>
<p>Failure:<br>
test_03(TestDRbSSLCore) [/home/naruse/ruby/test/drb/drbtest.rb:138]:<br>
[DRb::DRbConnError] exception expected, not<br>
Class: <a href="Errno::ECONNRESET" class="external">Errno::ECONNRESET</a><br>
Message: <"Connection reset by peer"><br>
---Backtrace---<br>
/home/naruse/ruby/test/drb/drbtest.rb:139:in <code>block in test_03' /home/naruse/ruby/test/drb/drbtest.rb:138:in </code>test_03'</p>
</li>
</ol>
<hr>
<ol start="3">
<li>Failure:<br>
test_07_public_private_protected_missing(TestDRbSSLCore) [/home/naruse/ruby/test/drb/drbtest.rb:182]:<br>
Exception raised:<br>
<#<Errno::ECONNRESET: Connection reset by peer>>.</li>
</ol>
<p>これらに共通するのは「Errno::ECONNRESET: Connection reset by peer」という例外が発生している点です。<br>
この例外は socket の close(2) を呼んだ際に errno に ECONNRESET がセットされたときに発生します。<br>
しかし、この挙動は POSIX 仕様外であり、FreeBSD 独自のものです。</p>
<p><a href="http://www.freebsd.org/cgi/man.cgi?query=close&apropos=0&sektion=0&manpath=FreeBSD+8.0-RELEASE&format=html" class="external">http://www.freebsd.org/cgi/man.cgi?query=close&apropos=0&sektion=0&manpath=FreeBSD+8.0-RELEASE&format=html</a><br>
<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/close.html" class="external">http://www.opengroup.org/onlinepubs/9699919799/functions/close.html</a><br>
<a href="http://netbsd.gw.com/cgi-bin/man-cgi?close++NetBSD-current" class="external">http://netbsd.gw.com/cgi-bin/man-cgi?close++NetBSD-current</a><br>
<a href="http://www.openbsd.org/cgi-bin/man.cgi?query=close&apropos=0&sektion=0&manpath=OpenBSD+Current&arch=i386&format=html" class="external">http://www.openbsd.org/cgi-bin/man.cgi?query=close&apropos=0&sektion=0&manpath=OpenBSD+Current&arch=i386&format=html</a><br>
<a href="http://leaf.dragonflybsd.org/cgi/web-man?command=close&section=ANY" class="external">http://leaf.dragonflybsd.org/cgi/web-man?command=close&section=ANY</a><br>
<a href="http://www.kernel.org/doc/man-pages/online/pages/man2/close.2.html" class="external">http://www.kernel.org/doc/man-pages/online/pages/man2/close.2.html</a><br>
<a href="http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man2/close.2.html" class="external">http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man2/close.2.html</a></p>
<p>これが結果的に、他の OS では例外が投げられない状況で例外が発生するという現象を生み出しています。<br>
以下は関連する議論です。<br>
<a href="http://old.nabble.com/close()-failing-with-ECONNRESET-td28817716.html" class="external">http://old.nabble.com/close()-failing-with-ECONNRESET-td28817716.html</a><br>
<a href="http://old.nabble.com/Re:-kern-146845:--libc--close(2)-returns-error-54-(connection-reset-by-peer)-wrongly-td28649525.html" class="external">http://old.nabble.com/Re:-kern-146845:--libc--close(2)-returns-error-54-(connection-reset-by-peer)-wrongly-td28649525.html</a></p>
<p>で、Ruby における対策ですが、close(2) で errno に ECONNRESET がセットされた場合、<br>
それを無視するべきだと思います。<br>
いかがそのパッチなのですがいかがでしょうか。</p>
<p>diff --git a/io.c b/io.c<br>
index 05b2d45..a1b49d2 100644<br>
--- a/io.c<br>
+++ b/io.c<br>
@@ -3436,7 +3436,7 @@ fptr_finalize(rb_io_t <em>fptr, int noraise)<br>
/</em> fptr->fd may be closed even if close fails.<br>
* POSIX doesn't specify it.<br>
* We assumes it is closed. */</p>
<ul>
<li>
<pre><code> if (close(fptr->fd) < 0 && NIL_P(err))
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> if (close(fptr->fd) < 0 && NIL_P(err) && errno != ECONNRESET)
err = noraise ? Qtrue : INT2NUM(errno);
</code></pre>
}<br>
skip_fd_close:<br>
=end</li>
</ul>
Backport186 - Backport #3403 (Closed): A bug related to ruby's regular expression!!!!!!
https://redmine.ruby-lang.org/issues/3403
2010-06-07T16:01:37Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
Backport r28192</p>
<p>I found a bug related to ruby's regular expression!<br>
puts(/wo{0,3}?/.match("woo"))<br>
This line of code should show a "w" on the screen, but my ruby shows "wo" on then screen.<br>
According to the principles of regular expression, this is a non-greedy match, so it should match 0 "o", but it matches at least 1 "o". I think this is a bug!<br>
I also tried this in the javascript language, it works well!("w" is shown)</p>
<p>My ruby version is v1.8.7-p249.<br>
=end</p>
Backport187 - Backport #3402 (Closed): A bug related to ruby's regular expression!!!!!!
https://redmine.ruby-lang.org/issues/3402
2010-06-07T16:00:55Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
Backport r28192</p>
<p>I found a bug related to ruby's regular expression!<br>
puts(/wo{0,3}?/.match("woo"))<br>
This line of code should show a "w" on the screen, but my ruby shows "wo" on then screen.<br>
According to the principles of regular expression, this is a non-greedy match, so it should match 0 "o", but it matches at least 1 "o". I think this is a bug!<br>
I also tried this in the javascript language, it works well!("w" is shown)</p>
<p>My ruby version is v1.8.7-p249.<br>
=end</p>
Ruby master - Feature #3036 (Closed): String#encode(to, from, opt) の opt[:replace] に Hash
https://redmine.ruby-lang.org/issues/3036
2010-03-29T16:11:29Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
<a href="https://blade.ruby-lang.org/ruby-dev/40540">[ruby-dev:40540]</a> の String#encode(to, from, opt) の opt[:replace] に Hash の話を、<br>
別にチケットとして起こしておきます</p>
<p>String#encode(to, from, opt) の opt[:replace] に Hash を与えられるようにして、<br>
そこに、変換元 encoding の文字 => 変換先の文字、という未定義文字の fallback 変換表を与えられるようにする、<br>
というものを今考えています。<br>
これだと例えば、<br>
fallbacks = {<br>
?¥uE6AD => "[ふくろ]",<br>
?¥u{1F4BA} => "[いす]"<br>
}<br>
"¥u{3042 E6AD 1F4BA}".encode("UTF8-KDDI", replace: fallbacks) #=> "あ[ふくろ][いす]"<br>
=end</p>
Ruby master - Feature #2968 (Rejected): 数値の正負を返すメソッド
https://redmine.ruby-lang.org/issues/2968
2010-03-16T03:38:54Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
数値の正負を返すメソッドが欲しいです。<br>
主たる想定用途は 0.0 と -0.0 を区別したいときです。<br>
これは、0.0 > -0.0 や 0.0 == -0.0 では知ることができません。<br>
とりあえず flo.to_s[0] == ?- で知ることができますが、これではあんまりです。</p>
<p>悩みどころはいつもの通りメソッド名ですが、</p>
<ul>
<li>Numeric#positive? と Numeric#negative?</li>
<li>Numeric#sign -> 負で -1、正で 1</li>
<li>Numeric#sign? -> 負で true, 正で false (signbit(3) に習う)<br>
あたりでしょうか。</li>
</ul>
<p>いかがでしょう。<br>
=end</p>
Ruby 1.8 - Bug #2761 (Closed): weird behaviour of readline on OSX 10.6
https://redmine.ruby-lang.org/issues/2761
2010-02-19T05:36:42Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
Hi,</p>
<p>You seems to use Ruby 1.8.x.<br>
So can you try following?</p>
<a name="Index-extreadlinereadlinec"></a>
<h1 >Index: ext/readline/readline.c<a href="#Index-extreadlinereadlinec" class="wiki-anchor">¶</a></h1>
<p>--- ext/readline/readline.c (revision 26664)<br>
+++ ext/readline/readline.c (working copy)<br>
@@ -833,6 +833,12 @@<br>
#ifdef HAVE_RL_EVENT_HOOK<br>
rl_event_hook = readline_event;<br>
#endif<br>
+#ifdef HAVE_RL_CATCH_SIGNALS</p>
<ul>
<li>rl_catch_signals = 0;<br>
+#endif<br>
+#ifdef HAVE_RL_CATCH_SIGWINCH</li>
<li>rl_catch_sigwinch = 0;<br>
+#endif<br>
#ifdef HAVE_RL_CLEAR_SIGNALS<br>
rl_clear_signals();<br>
#endif<br>
Index: ext/readline/extconf.rb<br>
===================================================================<br>
--- ext/readline/extconf.rb (revision 26664)<br>
+++ ext/readline/extconf.rb (working copy)<br>
@@ -59,6 +59,9 @@<br>
have_readline_var("rl_attempted_completion_over")<br>
have_readline_var("rl_library_version")<br>
have_readline_var("rl_event_hook")<br>
+# workaround for native windows.<br>
+/mswin|bccwin|mingw/ !~ RUBY_PLATFORM && have_readline_var("rl_catch_sigwinch")<br>
+/mswin|bccwin|mingw/ !~ RUBY_PLATFORM && have_readline_var("rl_catch_signals")<br>
have_readline_func("rl_cleanup_after_signal")<br>
have_readline_func("rl_clear_signals")<br>
have_readline_func("rl_vi_editing_mode")</li>
</ul>
<p>(2010/02/19 4:59), Andrew Eberbach wrote:</p>
<blockquote>
<p>Hi</p>
<p>I've been noticing that irb (and as a result script/console in rails)<br>
don't behave correctly with Control C. Nothing would happen when I hit<br>
control C until I hit enter or a few more keys and then it would clear<br>
the line and show a ^C and reset to the prompt. This doesn't happen on<br>
Linux and it didn't happen on 10.5</p>
<p>If there's a long running process in irb hitting control c works as<br>
expected but not if it's just sitting at a prompt.</p>
<p>I played around with the ext/readline.c and found that if I put a</p>
<p>rl_catch_signals = 0;</p>
<p>(see <a href="http://tiswww.case.edu/php/chet/readline/readline.html" class="external">http://tiswww.case.edu/php/chet/readline/readline.html</a>)</p>
<p>in Init_readline()</p>
<p>Then everything works as normal. Should this be added as a patch?<br>
Reading the readline docs it seems to me that what's happening is the<br>
internal readline handler gets stuck sending SIGINT back to the ruby<br>
process even though there's a trap("SIGINT") defined. Any ideas?</p>
<p>Andrew</p>
</blockquote>
<p>--<br>
NARUSE, Yui <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a><br>
=end</p>
Ruby master - Bug #2748 (Closed): fix for READ_CHECK causes failures on FreeBSD 8.0
https://redmine.ruby-lang.org/issues/2748
2010-02-16T03:41:08Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
間を置いてからの報告で申し訳ないのですが、例の READ_CHECK の修正 (r26625) が、<br>
FreeBSD での test-all の失敗を増やします。<br>
r26625 を revert するとこれらのテストは成功するようになります。</p>
<ol>
<li>
<p>Failure:<br>
test_read_error(TestIO) [/home/naruse/ruby/test/ruby/test_io.rb:869]:<br>
RuntimeError expected but nothing was raised.</p>
</li>
<li>
<p>Failure:<br>
test_readpartial_error(TestIO) [/home/naruse/ruby/test/ruby/test_io.rb:834]:<br>
RuntimeError expected but nothing was raised.<br>
=end</p>
</li>
</ol>
Ruby master - Feature #2635 (Rejected): Unbundle rdoc
https://redmine.ruby-lang.org/issues/2635
2010-01-23T23:20:56Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
The rdoc in trunk is outdated and not maintained,<br>
and latest rdoc is in gen.</p>
<p>I think Ruby 1.9 shouldn't bundle such old rdoc.<br>
People who needs rdoc should install from gem.<br>
=end</p>
Backport191 - Backport #2477 (Closed): String#split should be ASCII sensitive
https://redmine.ruby-lang.org/issues/2477
2009-12-14T15:51:40Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
If r24544 is backported, r24934 is also worth backported.</p>
<p>Author: naruse <a href="mailto:naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e" class="email">naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e</a><br>
Date: Tue Sep 15 05:27:29 2009 +0000</p>
<pre><code> Use rb_isspace for ASCII-incompatible strings.
* string.c (rb_str_split_m): use rb_isspace when the string
may be ASCII-incompatible.
(rb_str_lstrip_bang): ditto.
(rb_str_rstrip_bang): ditto.
</code></pre>
<p>=end</p>
Ruby master - Bug #2386 (Closed): r25230 causes SEGV arround Marshal
https://redmine.ruby-lang.org/issues/2386
2009-11-20T07:54:42Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
以下のコミット以降、後述の現象が発生するそうです。</p>
<p>Author: nobu <a href="mailto:nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e" class="email">nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e</a><br>
Date: Sun Oct 4 10:30:56 2009 +0000</p>
<pre><code>* marshal.c (struct {dump,load}_arg): manage with dfree, instead
of using local variable which may be moved by context switch.
<a href="https://blade.ruby-lang.org/ruby-dev/39425">[ruby-dev:39425]</a>
</code></pre>
<p><a href="http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=25230" class="external">http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=25230</a></p>
<hr>
<p>けいじゅ@いしつかです.</p>
<p>最新版のrubyで以下のメッセージが出るようになってしまったのですが, これ<br>
はどのような意味でしょうか?</p>
<p>% ruby -v<br>
ruby 1.9.2dev (2009-11-19 trunk 25848) [i686-linux]</p>
<p>each: method `to_s' called on hidden object (0x9438e48)</p>
<p>また, これを調べていたら: 以下のようなSEGVも発生するようになってしまい<br>
ました... なんか, 関係あるでしょうか?</p>
<a name="rubyのバージョンは微妙に違います"></a>
<h1 >rubyのバージョンは微妙に違います.<a href="#rubyのバージョンは微妙に違います" class="wiki-anchor">¶</a></h1>
<p>/usr/local/apps/rubyware/ruby-1.9.2-20091118/lib/ruby/1.9.1/delegate.rb:265: [BUG] Segmentation fault<br>
ruby 1.9.2dev (2009-11-18 trunk 25846) [i686-linux]</p>
<h2>-- control frame ----------<br>
c:0037 p:---- s:0130 b:0130 l:000129 d:000129 CFUNC :write<br>
c:0036 p:0026 s:0126 b:0126 l:000768 d:000125 LAMBDA /usr/local/apps/rubyware/ruby-1.9.2-20091118/lib/ruby/1.9.1/delegate.rb:265<br>
c:0035 p:---- s:0121 b:0121 l:000120 d:000120 FINISH<br>
c:0034 p:---- s:0119 b:0119 l:000118 d:000118 CFUNC :dump<br>
c:0033 p:0062 s:0114 b:0114 l:000ba8 d:000113 BLOCK /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/port.rb:863<br>
c:0032 p:0050 s:0110 b:0110 l:000109 d:000109 METHOD /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/port.rb:849<br>
c:0031 p:0011 s:0105 b:0105 l:000ba8 d:000ba8 METHOD /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/port.rb:859<br>
c:0030 p:0079 s:0101 b:0101 l:000095 d:000100 BLOCK /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/port.rb:787<br>
c:0029 p:0019 s:0099 b:0099 l:000098 d:000098 METHOD <a href="internal:prelude" class="external">internal:prelude</a>:8<br>
c:0028 p:0013 s:0096 b:0096 l:000095 d:000095 METHOD /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/port.rb:780<br>
c:0027 p:0015 s:0092 b:0092 l:000091 d:000091 METHOD /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/port.rb:303<br>
c:0026 p:0118 s:0088 b:0088 l:001e8c d:000087 BLOCK /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/n-group-by.rb:56<br>
c:0025 p:---- s:0083 b:0083 l:000082 d:000082 FINISH<br>
c:0024 p:---- s:0081 b:0081 l:000080 d:000080 CFUNC :call<br>
c:0023 p:0014 s:0077 b:0077 l:0011ec d:000076 BLOCK test/testc.rb:3196<br>
c:0022 p:---- s:0074 b:0074 l:000073 d:000073 FINISH<br>
c:0021 p:---- s:0072 b:0072 l:000071 d:000071 CFUNC :each<br>
c:0020 p:0032 s:0069 b:0069 l:0011ec d:00263c BLOCK test/testc.rb:3195<br>
c:0019 p:---- s:0065 b:0065 l:000064 d:000064 FINISH<br>
c:0018 p:---- s:0063 b:0063 l:000062 d:000062 CFUNC :each<br>
c:0017 p:0017 s:0060 b:0060 l:000059 d:000059 METHOD /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/nfile.rb:78<br>
c:0016 p:0073 s:0056 b:0056 l:000055 d:000055 METHOD /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/njob.rb:156<br>
c:0015 p:0011 s:0051 b:0051 l:0011ec d:00074c BLOCK test/testc.rb:3188<br>
c:0014 p:---- s:0047 b:0047 l:000046 d:000046 FINISH<br>
c:0013 p:---- s:0045 b:0045 l:000044 d:000044 CFUNC :yield<br>
c:0012 p:0014 s:0040 b:0040 l:0000dc d:000039 BLOCK /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/share/block-source.rb:81<br>
c:0011 p:0021 s:0038 b:0038 l:000037 d:000037 METHOD /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/share/stdout.rb:35<br>
c:0010 p:0014 s:0034 b:0034 l:0000dc d:0000dc METHOD /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/share/block-source.rb:80<br>
c:0009 p:0043 s:0029 b:0029 l:000028 d:000028 METHOD /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/n-each-substream-mapper.rb:26<br>
c:0008 p:0073 s:0025 b:0025 l:000024 d:000024 METHOD /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/njob.rb:156<br>
c:0007 p:0137 s:0020 b:0020 l:001e8c d:001f2c BLOCK /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/n-group-by.rb:47<br>
c:0006 p:---- s:0016 b:0016 l:000015 d:000015 FINISH<br>
c:0005 p:---- s:0014 b:0014 l:000013 d:000013 CFUNC :call<br>
c:0004 p:0012 s:0011 b:0011 l:000010 d:000010 METHOD /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/njob.rb:143<br>
c:0003 p:0077 s:0007 b:0007 l:0020f8 d:000006 BLOCK /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/njob.rb:125<br>
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH<br>
c:0001 p:---- s:0002 b:0002 l:000001 d:000001 TOP</h2>
<p>/home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/njob.rb:125:in <code>block in start' /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/njob.rb:143:in </code>basic_start'<br>
/home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/njob.rb:143:in <code>call' /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/n-group-by.rb:47:in </code>block in start_export'<br>
/home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/njob.rb:156:in <code>each' /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/n-each-substream-mapper.rb:26:in </code>basic_each'<br>
/home/keiju/public/a.research/fairy/git/fairy/lib/fairy/share/block-source.rb:80:in <code>yield19' /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/share/stdout.rb:35:in </code>replace_stdout'<br>
/home/keiju/public/a.research/fairy/git/fairy/lib/fairy/share/block-source.rb:81:in <code>block in yield19' /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/share/block-source.rb:81:in </code>yield'<br>
test/testc.rb:3188:in <code>block in context' /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/njob.rb:156:in </code>each'<br>
/home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/nfile.rb:78:in <code>basic_each' /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/nfile.rb:78:in </code>each'<br>
test/testc.rb:3195:in <code>block (2 levels) in context' test/testc.rb:3195:in </code>each'<br>
test/testc.rb:3196:in <code>block (3 levels) in context' test/testc.rb:3196:in </code>call'<br>
/home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/n-group-by.rb:56:in <code>block (2 levels) in start_export' /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/port.rb:303:in </code>push'<br>
/home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/port.rb:780:in <code>push' <internal:prelude>:8:in </code>synchronize'<br>
/home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/port.rb:787:in <code>block in push' /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/port.rb:859:in </code>store_2ndmemory'<br>
/home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/port.rb:849:in <code>open_2ndmemory' /home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/port.rb:863:in </code>block in store_2ndmemory'<br>
/home/keiju/public/a.research/fairy/git/fairy/lib/fairy/node/port.rb:863:in <code>dump' /usr/local/apps/rubyware/ruby-1.9.2-20091118/lib/ruby/1.9.1/delegate.rb:265:in </code>block in delegating_block'<br>
/usr/local/apps/rubyware/ruby-1.9.2-20091118/lib/ruby/1.9.1/delegate.rb:265:in `write'</p>
<p>-- C level backtrace information -------------------------------------------<br>
fairy processor --node 45566 --id 0(rb_vm_bugreport+0xb5) [0x81621a5]<br>
fairy processor --node 45566 --id 0 [0x819f3ce]<br>
fairy processor --node 45566 --id 0(rb_bug+0x28) [0x819f468]<br>
fairy processor --node 45566 --id 0 [0x80f71e5]<br>
[0xb801c40c]<br>
fairy processor --node 45566 --id 0(rb_funcall+0xe1) [0x815ee81]<br>
fairy processor --node 45566 --id 0(rb_obj_as_string+0x81) [0x8103811]<br>
fairy processor --node 45566 --id 0 [0x8079378]<br>
fairy processor --node 45566 --id 0 [0x8151689]<br>
fairy processor --node 45566 --id 0 [0x8152bbd]<br>
fairy processor --node 45566 --id 0 [0x815511d]<br>
fairy processor --node 45566 --id 0 [0x8159399]<br>
fairy processor --node 45566 --id 0(rb_vm_invoke_proc+0x81) [0x8159b61]<br>
fairy processor --node 45566 --id 0 [0x815aab5]<br>
fairy processor --node 45566 --id 0(rb_funcall+0x18e) [0x815ef2e]<br>
fairy processor --node 45566 --id 0(rb_io_write+0x29) [0x80712a9]<br>
fairy processor --node 45566 --id 0 [0x8089f38]<br>
fairy processor --node 45566 --id 0 [0x814d71d]<br>
fairy processor --node 45566 --id 0 [0x8151689]<br>
fairy processor --node 45566 --id 0 [0x8152bbd]<br>
fairy processor --node 45566 --id 0 [0x815511d]<br>
fairy processor --node 45566 --id 0 [0x8159399]<br>
fairy processor --node 45566 --id 0(rb_vm_invoke_proc+0x81) [0x8159b61]<br>
fairy processor --node 45566 --id 0 [0x8062ec4]<br>
fairy processor --node 45566 --id 0 [0x814d71d]<br>
fairy processor --node 45566 --id 0 [0x8151689]<br>
fairy processor --node 45566 --id 0 [0x8152bbd]<br>
fairy processor --node 45566 --id 0 [0x815511d]<br>
fairy processor --node 45566 --id 0 [0x8159399]<br>
fairy processor --node 45566 --id 0(rb_yield+0x4f) [0x816103f]<br>
fairy processor --node 45566 --id 0(rb_ary_each+0x41) [0x81716a1]<br>
fairy processor --node 45566 --id 0 [0x8151689]<br>
fairy processor --node 45566 --id 0 [0x8152bbd]<br>
fairy processor --node 45566 --id 0 [0x815511d]<br>
fairy processor --node 45566 --id 0 [0x8159399]<br>
fairy processor --node 45566 --id 0(rb_yield+0x4f) [0x816103f]<br>
fairy processor --node 45566 --id 0 [0x8082bf8]<br>
fairy processor --node 45566 --id 0 [0x814d71d]<br>
fairy processor --node 45566 --id 0 [0x8151689]<br>
fairy processor --node 45566 --id 0 [0x8152bbd]<br>
fairy processor --node 45566 --id 0 [0x815511d]<br>
fairy processor --node 45566 --id 0 [0x8159399]<br>
fairy processor --node 45566 --id 0(rb_vm_invoke_proc+0x81) [0x8159b61]<br>
fairy processor --node 45566 --id 0 [0x8062ec4]<br>
fairy processor --node 45566 --id 0 [0x814d71d]<br>
fairy processor --node 45566 --id 0 [0x8151689]<br>
fairy processor --node 45566 --id 0 [0x8152bbd]<br>
fairy processor --node 45566 --id 0 [0x815511d]<br>
fairy processor --node 45566 --id 0 [0x8159399]<br>
fairy processor --node 45566 --id 0(rb_vm_invoke_proc+0x81) [0x8159b61]<br>
fairy processor --node 45566 --id 0 [0x8062ec4]<br>
fairy processor --node 45566 --id 0 [0x814d71d]<br>
fairy processor --node 45566 --id 0 [0x8151689]<br>
fairy processor --node 45566 --id 0 [0x8152bbd]<br>
fairy processor --node 45566 --id 0 [0x815511d]<br>
fairy processor --node 45566 --id 0 [0x8159399]<br>
fairy processor --node 45566 --id 0(rb_vm_invoke_proc+0x81) [0x8159b61]<br>
fairy processor --node 45566 --id 0 [0x81682ed]<br>
fairy processor --node 45566 --id 0 [0x81683a1]<br>
/lib/i686/cmov/libpthread.so.0 [0xb7fe84b5]<br>
/lib/i686/cmov/libc.so.6(clone+0x5e) [0xb7efea5e]</p>
<p>--<br>
NARUSE, Yui <a href="mailto:naruse@airemix.jp" class="email">naruse@airemix.jp</a><br>
=end</p>
Ruby master - Bug #2208 (Rejected): Exception#inspect の message 部が inspect されていない
https://redmine.ruby-lang.org/issues/2208
2009-10-14T17:38:54Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
通常 Object#inspect の結果にでてくる文字列は inspect されています。<br>
しかし、Exception#inspect はそのままになっています。<br>
<a href="http://shinh.skr.jp/m/?date=20091014#c02" class="external">http://shinh.skr.jp/m/?date=20091014#c02</a></p>
<p>class Foo;def initialize;@a="\t";end;end<br>
Foo.new.inspect #=> #<Foo:0x000008012dffd8 <a class="user active user-mention" href="https://redmine.ruby-lang.org/users/52980">@A (A A)</a>="\t"></p>
<p>Exception.new("\t") #=> #<Exception: " "></p>
<p>単なるかけ忘れな気がするのですがどうでしょう。</p>
<p>diff --git a/error.c b/error.c<br>
index a7342de..3a5580a 100644<br>
--- a/error.c<br>
+++ b/error.c<br>
@@ -458,7 +458,7 @@ exc_exception(int argc, VALUE *argv, VALUE self)<br>
static VALUE<br>
exc_to_s(VALUE exc)<br>
{</p>
<ul>
<li>VALUE mesg = rb_attr_get(exc, rb_intern("mesg"));</li>
</ul>
<ul>
<li>
<p>VALUE mesg = rb_inspect(rb_attr_get(exc, rb_intern("mesg")));</p>
<p>if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc));<br>
if (OBJ_TAINTED(exc)) OBJ_TAINT(mesg);<br>
=end</p>
</li>
</ul>
Ruby master - Feature #2166 (Rejected): Add CreationError
https://redmine.ruby-lang.org/issues/2166
2009-10-01T00:33:34Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin</p>
<blockquote>
<p>Here is a patch which implements the CreationError exception class,<br>
as documented in the Tempfile API documentation. However,<br>
I could not write a unit test for it because there seems<br>
to be no mocking/stubbing framework that I could use.</p>
</blockquote>
<p>Originally <a href="/issues/1999">[ruby-core:25131]</a> and patch is there.<br>
=end</p>
Ruby master - Feature #2093 (Closed): String#stripの対象は\sか[:space:]か
https://redmine.ruby-lang.org/issues/2093
2009-09-13T02:24:49Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
現在、String#strip は rb_enc_isspace を使っています。<br>
つまり、[:space:] にマッチするものを落とすため、<br>
例えばいわゆる全角空白等も切り落とす対象になっています。</p>
<p>しかし、他の Ruby core API は ASCII を意識した動きをすることが多く、<br>
strip はちょっと予想を裏切る動作になっています。</p>
<p>なんとなくただの修正漏れのように感じるのですがどうでしょう?<br>
=end</p>
Ruby master - Feature #2032 (Closed): Change the license to "GPLv2+ or Ruby's original".
https://redmine.ruby-lang.org/issues/2032
2009-09-02T17:44:13Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
This is moved ticked from ruby-dev.<br>
Original post and ticket is <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Change the license to "GPLv2+ or Ruby's original". (Closed)" href="https://redmine.ruby-lang.org/issues/2000">#2000</a> in English.</p>
<p>----- Original Post -----</p>
<p>Hello.</p>
<p>Recently readline 6.0 was released and its license was changed from<br>
GPLv2+ (GPL version 2 and any later) to GPLv3+ [1][2]<br>
Unfortunately Ruby's license is still under GPLv2 and Ruby's original license [3],<br>
which is incompatible with GPLv3 [4]. So unless Ruby's license is changed<br>
to "GPLv2+ or Ruby's original license" or so , Ruby's readline module cannot be shipped<br>
any more. Note that "Ruby's original license" is regarded as incompatible with<br>
GPL [5].</p>
<p>So please change the Ruby's license to GPLv3 (and GPLv2) compat.</p>
<p>[1] <a href="http://tiswww.case.edu/php/chet/readline/rltop.html" class="external">http://tiswww.case.edu/php/chet/readline/rltop.html</a><br>
[2] <a href="https://www.redhat.com/archives/fedora-devel-list/2009-July/msg00192.html" class="external">https://www.redhat.com/archives/fedora-devel-list/2009-July/msg00192.html</a><br>
[3] <a href="http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/COPYING?view=co" class="external">http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/COPYING?view=co</a><br>
[4] <a href="https://fedoraproject.org/wiki/Licensing#GPL_Compatibility_Matrix" class="external">https://fedoraproject.org/wiki/Licensing#GPL_Compatibility_Matrix</a><br>
[5] <a href="https://fedoraproject.org/wiki/Licensing" class="external">https://fedoraproject.org/wiki/Licensing</a><br>
=end</p>
Ruby master - Feature #1951 (Closed): openのBOM指定拡張
https://redmine.ruby-lang.org/issues/1951
2009-08-18T23:47:15Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>#747と#802で議論された、openのBOM指定拡張ですが、現在の仕様は、</p>
<ul>
<li>BOMを捨てる</li>
<li>BOMを見てencodingを設定する<br>
という2つの機能が混在しています。</li>
</ul>
<p>このために、たとえば「<code>UTF-8-BOM</code>」という指定でも、<br>
BOMがUTF-16LEを示していた場合には実際に返ってくるStringはUTF-16LEになってしまいます。</p>
<p>この問題に対する解決案として、</p>
<ul>
<li>UTF-*-BOM はBOMを捨てるだけ。別のencodingだった場合は例外</li>
<li>
<code>BOM|UTF-*</code>を追加、これが現在の<code>UTF-*-BOM</code>相当の動作 (BOMを見る OR <code>UTF-*</code>と指定、というイメージ)<br>
というものを考えています。</li>
</ul>
<p>皆さんはどのように思われますか?</p>
Ruby master - Feature #1949 (Closed): Warn needless escaped characters
https://redmine.ruby-lang.org/issues/1949
2009-08-18T22:25:48Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
正規表現内での不必要なエスケープに警告を出しませんか。</p>
<p>動機としては、/\uXXXX/の非互換性の話があります。</p>
<p>これは、Ruby 1.8において、不必要なエスケープであった/\u/が、<br>
Ruby 1.9においては\uXXXXという構文が追加されたがために、<br>
エラーが出たり意味が変わってしまったりしたという話でした。</p>
<p>このような不幸な出来事は、/\u/と書いたら警告を出すようにしていたら、<br>
未然に防ぐことができたり、被害を減らすことができたかもしれません。</p>
<p>将来また別のエスケープ記法が追加される事は十分あり得る話だと思います。<br>
その際に同じ不幸を繰り返さないように、警告を出すようにしませんか。</p>
<p>具体的には、文字クラス外の<br>
g, i, j, k, l, m, o, p, q, y, E, F, H, I, J, K, L, N, O, P, Q, R, T, U, V, X, Y<br>
と、文字クラス内の<br>
g, i, j, k, l, m, o, p, q, y, z, A, B, E, F, G, H, I, J, K, L, N, O, P, Q, R, T, U, V, X, Y, Z<br>
あたりになるでしょうか。</p>
<p>なお、現状では警告が出ないが、すでにエスケープ記法として用いている、<br>
/\p/あたりは議論の余地のあるところかもしれません。<br>
=end</p>
Backport191 - Backport #1938 (Closed): FreeBSDでmakeに失敗する
https://redmine.ruby-lang.org/issues/1938
2009-08-14T16:56:45Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
common.mkに$(YACC) -d $(YFLAGS) -o y.tab.c $(<:=/)という行がありまして、<br>
これはLinuxとかWindowsでは動くんですが、BSD makeだとバックスラッシュがエスケープだと解釈され、<br>
「Unclosed substitution for < (= missing)」<br>
というエラーが出ます。</p>
<p>この問題はr22964で対処されています。<br>
=end</p>
Ruby master - Bug #527 (Closed): test_execopts_pgroup(TestProcess) fails on NetBSD
https://redmine.ruby-lang.org/issues/527
2008-08-31T15:54:10Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
以下のテストが NetBSD 4.99.72 i386 にて失敗します。</p>
<p>test_execopts_pgroup(TestProcess) [/home/naruse/src/ruby-trunk/test/ruby/test_process.rb:141]:<br>
<a href="Errno::EPERM" class="external">Errno::EPERM</a> exception expected but none was thrown.<br>
=end</p>
Ruby master - Bug #368 (Closed): 境界における Math.atanh 等の動作
https://redmine.ruby-lang.org/issues/368
2008-07-28T02:53:11Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
現在の Ruby trunk では、FreeBSD 7 において、<br>
test/ruby/test_math.rb は以下のように失敗します。</p>
<p>y% ruby19 test/ruby/test_math.rb<br>
Loaded suite test/ruby/test_math<br>
Started<br>
......F...........FFF.....<br>
Finished in 0.036791548 seconds.</p>
<ol>
<li>
<p>Failure:<br>
test_atanh(TestMath) [test/ruby/test_math.rb:97]:<br>
<[Errno::EDOM, Errno::ERANGE]> exception expected but none was thrown.</p>
</li>
<li>
<p>Failure:<br>
test_log(TestMath) [test/ruby/test_math.rb:113]:<br>
<[Errno::EDOM, Errno::ERANGE]> exception expected but none was thrown.</p>
</li>
<li>
<p>Failure:<br>
test_log10(TestMath) [test/ruby/test_math.rb:129]:<br>
<[Errno::EDOM, Errno::ERANGE]> exception expected but none was thrown.</p>
</li>
<li>
<p>Failure:<br>
test_log2(TestMath) [test/ruby/test_math.rb:121]:<br>
<[Errno::EDOM, Errno::ERANGE]> exception expected but none was thrown.</p>
</li>
</ol>
<p>26 tests, 126 assertions, 4 failures, 0 errors</p>
<p>これらの原因はいずれも境界における定義の違いに由来しているものと思わます。</p>
<p>例えば、NetBSD4 だと atanh のマニュアルには以下のようにあり、<br>
atanh(1) は NaN となります。</p>
<p>RETURN VALUES<br>
If |x|>=1, atanh(x) and atanhf(x) return +inf, -inf or NaN, and sets the<br>
global variable errno to EDOM.</p>
<p>しかし、FreeBSD7 では以下のようになっており、atanh(1) は infinity を返します。</p>
<p>RETURN VALUES<br>
The atanh() and the atanhf() functions return the inverse hyperbolic tan-<br>
gent of x if successful. If the argument has absolute value 1, a divide-<br>
by-zero exception is raised and an infinity is returned. If |x| > 1, an<br>
invalid exception is raised and an NaN is returned.</p>
<p>参考:<br>
<a href="http://www.hiroshima-cu.ac.jp/japanese/IPC/hunet99/sun/WorkShop/ja/html_docs/common-tools/numerical_comp_guide/standard.doc.html" class="external">http://www.hiroshima-cu.ac.jp/japanese/IPC/hunet99/sun/WorkShop/ja/html_docs/common-tools/numerical_comp_guide/standard.doc.html</a><br>
=end</p>