Ruby Issue Tracking System: Issues
https://redmine.ruby-lang.org/
https://redmine.ruby-lang.org/favicon.ico?1711330511
2020-12-26T11:04:18Z
Ruby Issue Tracking System
Redmine
Ruby master - Feature #17472 (Rejected): HashWithIndifferentAccess like Hash extension
https://redmine.ruby-lang.org/issues/17472
2020-12-26T11:04:18Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Rails has <a href="https://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html" class="external">ActiveSupport::HashWithIndifferentAccess</a>, which is widely used in Rails to handle Request, Session, ActionView's form construction, ActiveRecord's DB communication, and so on. It receives String or Symbol and normalize them to fetch the value. But it is implemented with Ruby. If we provide C implementation of that, Rails will gain the performance improvement.</p>
<p>summary of previous discussion: <a href="https://github.com/rails/rails/pull/40182#issuecomment-687607812" class="external">https://github.com/rails/rails/pull/40182#issuecomment-687607812</a></p>
Ruby master - Feature #17468 (Closed): Deprecate RUBY_DEVEL
https://redmine.ruby-lang.org/issues/17468
2020-12-25T09:32:50Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Some configuration of Ruby use RUBY_DEVEL, which depends PATCH_LEVEL.<br>
But depending PATCH_LEVEL causes issues which will become revealed on the final release.<br>
Though we release some previews and RCs, they don't contributes the quality around RUBY_DEVEL.</p>
<p>Therefore to ensure CI tests the quality of the final release, we need to deprecate RUBY_DEVEL.</p>
Ruby master - Feature #16275 (Closed): Revert `.:` syntax
https://redmine.ruby-lang.org/issues/16275
2019-10-23T15:26:13Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p><code>obj.:method</code> is introduced at r66667 by <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Proposal: Shorthand operator for Object#method (Open)" href="https://redmine.ruby-lang.org/issues/12125">#12125</a> and <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Syntax sugar for method reference (Closed)" href="https://redmine.ruby-lang.org/issues/13581">#13581</a>.<br>
It encourages the functional programming style in Ruby.</p>
<p>But this shorthand syntax is just for methods of <code>self</code> without arguments.<br>
It causes another feature requests like <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Proposal: Shorthand operator for "#instance_method" (Open)" href="https://redmine.ruby-lang.org/issues/16273">#16273</a> (and lambda compositions like <a class="issue tracker-1 status-7 priority-4 priority-default closed" title="Bug: Refactor Proc#>> and #<< (Feedback)" href="https://redmine.ruby-lang.org/issues/15428">#15428</a>).</p>
<p>Such features will introduce a new view of Ruby but no one illustrates the whole picture yet.<br>
I worried about such patch work may cause a conflict with future expansion of functional programing style or a just a garbage feature.</p>
<p><code>.:</code> syntax is introduced in 2.7.0 preview1, not released in production yet.<br>
How about reverting at this time and re-introduce with a big picture.</p>
Ruby master - Feature #16131 (Closed): Remove $SAFE, taint and trust
https://redmine.ruby-lang.org/issues/16131
2019-08-29T07:14:34Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Ruby had Taint checking which is originally introduced in Perl.<br>
<a href="https://en.wikipedia.org/wiki/Taint_checking" class="external">https://en.wikipedia.org/wiki/Taint_checking</a></p>
<p>It was intended to provide a useful tool for handle objects which are come from outside.<br>
Input data is set as tainted by default and call untaint if you checked or filtered the value.<br>
Some people used this feature in the age of CGI.</p>
<p>But these days, no one use the mechanism and input libraries usually doesn't support it.<br>
For example rack, as following shows its input is not tainted and the mechanism is unusable.</p>
<pre><code>% cat foo.ru
run ->(env) do
['200', {'Content-Type' => 'text/plain'}, ["Is QUERY_STRING tainted?: #{env["QUERY_STRING"].tainted?}"]]
end
% rackup foo.ru
[51724] Puma starting in cluster mode...
[51724] * Version 3.12.1 (ruby 2.6.3-p62), codename: Llamas in Pajamas
[51724] * Min threads: 3, max threads: 3
[51724] * Environment: development
[51724] * Process workers: 1
[51724] * Preloading application
[51724] * Listening on tcp://localhost:9292
[51724] Use Ctrl-C to stop
[51737] + Gemfile in context: /Users/naruse/work/td-cdp-api/Gemfile
[51724] - Worker 0 (pid: 51737) booted, phase: 0
</code></pre>
<pre><code>% curl http://localhost:9292/\?foo=1
Is QUERY_STRING tainted?: false
</code></pre>
<p>Therefore I think Taint checking mechanism is unusable on the current Ruby ecosystem.</p>
<p>On the other hand we experienced multiple vulnerability around $SAFE and taint mechanism.<br>
<a href="https://cse.google.com/cse?q=taint&cx=008288045305770251182%3Afvruzsaknew&ie=UTF-8" class="external">https://cse.google.com/cse?q=taint&cx=008288045305770251182%3Afvruzsaknew&ie=UTF-8</a><br>
The cost of maintaining it is expensive.</p>
<p>In conclusion, I think the taint mechanism is too expensive to maintain for the merit of it.<br>
I suggest to remove it.</p>
Ruby master - Bug #15992 (Closed): An exception breaks monitor state and cause deadlock
https://redmine.ruby-lang.org/issues/15992
2019-07-10T06:55:40Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>lib/monitor.rb provides Monitor.<br>
But its state handling is weak for interrupts caused by Thread.kill for example timeout libraries.</p>
<p>Timeout exception may happen everywhere. If it raised when the thread is executing</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">def</span> <span class="nf">mon_exit</span>
<span class="n">mon_check_owner</span>
<span class="vi">@mon_count</span> <span class="o">-=</span><span class="mi">1</span>
<span class="k">if</span> <span class="vi">@mon_count</span> <span class="o">==</span> <span class="mi">0</span>
<span class="vi">@mon_owner</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="c1"># HERE!!!</span>
<span class="vi">@mon_mutex</span><span class="p">.</span><span class="nf">unlock</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>It breaks the state of the monitor and it causes deadlock.</p>
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 - Bug #15398 (Closed): TestThread#test_signal_at_join fails on FreeBSD
https://redmine.ruby-lang.org/issues/15398
2018-12-11T09:10:02Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Since r64538 or r64539, TestThread#test_signal_at_join is failing on our FreeBSD CI.</p>
<pre><code>+ <n>) Error:
+TestThread#test_signal_at_join:
+Timeout::Error: execution of assert_separately expired timeout (120 sec)
+pid 80587 killed by SIGTERM (signal 15)
+| BAhvOhRTaWduYWxFeGNlcHRpb24KOgltZXNnIgxTSUdURVJNOgdidFsMSSIU
+| LTozNzppbiBgd3JpdGUnBjoGRUZJIhMtOjM3OmluIGBwdXRzJwY7CEZJIikt
+| OjM3OmluIGBibG9jayAoMiBsZXZlbHMpIGluIDxtYWluPicGOwhGSSIULToz
+| NDppbiBgdGltZXMnBjsIRkkiHi06MzQ6aW4gYGJsb2NrIGluIDxtYWluPicG
+| OwhGSSIULToxMDppbiBgcG9wZW4nBjsIRkkiFS06MTA6aW4gYDxtYWluPicG
+| OwhGOgpzaWdub2kUOgpjYXVzZTA6EWJ0X2xvY2F0aW9uc0AH
+| assertions=122
+|
</code></pre>
<p><a href="https://rubyci.org/logs/rubyci.s3.amazonaws.com/freebsd11zfs/ruby-trunk/log/20180826T003001Z.diff.html.gz" class="external">https://rubyci.org/logs/rubyci.s3.amazonaws.com/freebsd11zfs/ruby-trunk/log/20180826T003001Z.diff.html.gz</a></p>
<p>Note that this doesn't happen on my private FreeBSD box.</p>
Ruby master - Bug #15164 (Closed): mkmf doesn't work with miniruby on Windows
https://redmine.ruby-lang.org/issues/15164
2018-09-26T15:29:46Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>After r59449 <code>nmake</code> failes to run when making ripper and so on.<br>
It because miniruby sets UTF-8 encoding even though the content is CP932 (on Japanese Windows).<br>
It should set ASCII-8BIT and handle as it is.</p>
<pre><code>ripper:
" Could not be configured. It will not be installed."
" C:/ruby-trunk/lib/mkmf.rb:1560: invalid byte sequence in UTF-8"
" Check ext/ripper/mkmf.log for more details."
*** Fix the problems, then remove these directories and try again if you want.
</code></pre>
<p>Note that recent Windows sets PATH to paths under %APPDATA% for example<br>
C:\Users<UserNameInANSI>\AppData\Local\Microsoft\WindowsApps</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 - Bug #14208 (Closed): raise error if value contains CR/LF in iniheader of initialize...
https://redmine.ruby-lang.org/issues/14208
2017-12-20T12:04:47Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>like r59693, initialize_http_header also should raise error.</p>
<p><a href="https://twitter.com/DouweM/status/943441930142220289" class="external">https://twitter.com/DouweM/status/943441930142220289</a></p>
Ruby master - Bug #14186 (Closed): cannot build ruby with tarball on noruby environment
https://redmine.ruby-lang.org/issues/14186
2017-12-14T16:35:37Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>r61055 breaks build</p>
Ruby master - Bug #13945 (Closed): Backport r60024
https://redmine.ruby-lang.org/issues/13945
2017-09-27T21:48:05Z
naruse (Yui NARUSE)
naruse@airemix.jp
<pre><code>vm.c: fetch retval iff necessary
* vm.c (rb_vm_make_jump_tag_but_local_jump): get rid of fetching
retval when it is not used. it is necessary for local jump
state only.
</code></pre>
<p>This caused SEGV if an application which embeds Ruby and uses <code>rb_load_protect</code>.<br>
<a href="https://github.com/vim/vim/pull/2147" class="external">https://github.com/vim/vim/pull/2147</a></p>
Ruby master - Feature #13873 (Closed): Optimize Dir.glob with FNM_EXTGLOB
https://redmine.ruby-lang.org/issues/13873
2017-09-05T17:51:27Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Rails often queries Dir.glob with complex pattern.</p>
<p>On accessing Rails site, it calls glob as follows on querying templates.<br>
Note that Dir[] insists File::FNM_EXTGLOB.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">def</span> <span class="nf">find_template_paths</span><span class="p">(</span><span class="n">query</span><span class="p">)</span>
<span class="no">Dir</span><span class="p">[</span><span class="n">query</span><span class="p">].</span><span class="nf">uniq</span><span class="p">.</span><span class="nf">reject</span> <span class="k">do</span> <span class="o">|</span><span class="n">filename</span><span class="o">|</span>
<span class="no">File</span><span class="p">.</span><span class="nf">directory?</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span> <span class="o">||</span>
<span class="c1"># deals with case-insensitive file systems.</span>
<span class="o">!</span><span class="no">File</span><span class="p">.</span><span class="nf">fnmatch</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="no">File</span><span class="o">::</span><span class="no">FNM_EXTGLOB</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p><a href="https://github.com/rails/rails/blob/6f1c18308ebffc97d51440cdeed7be71de58f26a/actionview/lib/action_view/template/resolver.rb#L247" class="external">https://github.com/rails/rails/blob/6f1c18308ebffc97d51440cdeed7be71de58f26a/actionview/lib/action_view/template/resolver.rb#L247</a></p>
<p>For example on accessing index page of Post Model (/posts), it calls following glob:<br>
Dir["/home/naruse/foo/app/views/posts/index{.en,}{.html,.text,.js,.css,.ics,.csv,.vcf,.png,.jpeg,.gif,.bmp,.tiff,.svg,.mpeg,.xml,.rss,.atom,.yaml,.multipart_form,.url_encoded_form,.json,.pdf,.zip,.gzip,}{}{.raw,.erb,.html,.builder,.ruby,.coffee,.jbuilder,}"]'</p>
<p>It calls many stat as follows:</p>
<pre><code>% sudo strace ./miniruby58882 -e'Dir["/home/naruse/foo/app/views/posts/index{.en,}{.html,.text,.js,.css,.ics,.csv,.vcf,.png,.jpeg,.gif,.bmp,.tiff,.svg,.mpeg,.xml,.rss,.atom,.yaml,.multipart_form,.url_encoded_form,.json,.pdf,.zip,.gzip,}{}{.raw,.erb,.html,.builder,.ruby,.coffee,.jbuilder,}"]'|&grep newfstatat|wc -l
400
</code></pre>
<p>Because current glob implementation handles braces in early stage,<br>
then calls stat for each combination of brace patterns instead of using readdir results.</p>
<p>Below is a patch to use readdir instead of hundreds of syscalls.<br>
Note that this patch changes the order of the result as follows:</p>
<pre><code> 1) Failure:
TestDir#test_glob [/home/naruse/ruby/test/ruby/test_dir.rb:157]:
<["/tmp/test-all/__test_dir__20170906-8620-ka8yqu/}}{}",
"/tmp/test-all/__test_dir__20170906-8620-ka8yqu/}}a"]> expected but was
<["/tmp/test-all/__test_dir__20170906-8620-ka8yqu/}}a",
"/tmp/test-all/__test_dir__20170906-8620-ka8yqu/}}{}"]>.
</code></pre>
<pre><code>diff --git a/dir.c b/dir.c
index b7afaec4e0..7ca84fa8c5 100644
--- a/dir.c
+++ b/dir.c
@@ -290,6 +290,8 @@ bracket(
#define UNESCAPE(p) (escape && *(p) == '\\' ? (p) + 1 : (p))
#define ISEND(p) (!*(p) || (pathname && *(p) == '/'))
#define RETURN(val) return *pcur = p, *scur = s, (val);
+#define FNMATCH_ALLOC_N(type, n) ((type *)malloc(sizeof(type) * (n)))
+#define FNMATCH_FREE(ptr) free(ptr)
static int
fnmatch_helper(
@@ -348,6 +350,56 @@ fnmatch_helper(
}
goto failed;
}
+
+ case '{': {
+ size_t len = pend - p;
+ char *buf = FNMATCH_ALLOC_N(char, len);
+ const char *rbrace = NULL;
+ while (p < pend) {
+ const char *t = ++p;
+ int nest = 0;
+ while (p < pend && !(*p == ',' && nest == 0)) {
+ if (*p == '{') nest++;
+ if (*p == '}') {
+ if (nest == 0) {
+ if (!rbrace) rbrace = p;
+ goto rest;
+ }
+ nest--;
+ }
+ if (*p == '\\' && escape) {
+ if (++p >= pend) break;
+ }
+ Inc(p, pend, enc);
+ }
+ if (!rbrace) {
+ rbrace = p;
+ while (rbrace < pend && !(*rbrace == '}' && nest == 0)) {
+ if (*rbrace == '{') nest++;
+ if (*rbrace == '}') nest--;
+ if (*rbrace == '\\' && escape) {
+ if (++p >= pend) break;
+ }
+ Inc(rbrace, pend, enc);
+ }
+ }
+rest:
+ memcpy(buf, t, p-t);
+ buf[p-t]=0;
+ strlcpy(buf+(p-t), rbrace+1, len-(p-t));
+ {
+ const char *pp = buf, *ss = s;
+ r = fnmatch_helper((const char **)&pp, &ss, flags|FNM_DOTMATCH, enc);
+ }
+ if (r == 0) {
+ p = buf;
+ FNMATCH_FREE(buf);
+ RETURN(0);
+ }
+ if (p >= rbrace) break;
+ }
+ FNMATCH_FREE(buf);
+ }
}
/* ordinary */
@@ -1426,6 +1478,12 @@ has_magic(const char *p, const char *pend, int flags, rb_encoding *enc)
case '[':
return MAGICAL;
+ case '{':
+ if (flags & FNM_EXTGLOB) {
+ return MAGICAL;
+ }
+ break;
+
case '\\':
if (escape && p++ >= pend)
continue;
@@ -2272,6 +2330,13 @@ push_pattern(const char *path, VALUE ary, void *enc)
rb_ary_push(ary, name);
}
+struct push_glob_args {
+ struct glob_args glob;
+ int flags;
+ int fd;
+};
+static int push_caller(const char *path, VALUE val, void *enc);
+
static int
ruby_brace_expand(const char *str, int flags, ruby_glob_func *func, VALUE arg,
rb_encoding *enc, VALUE var)
@@ -2280,7 +2345,7 @@ ruby_brace_expand(const char *str, int flags, ruby_glob_func *func, VALUE arg,
const char *p = str;
const char *pend = p + strlen(p);
const char *s = p;
- const char *lbrace = 0, *rbrace = 0;
+ const char *lbrace = NULL, *rbrace = NULL;
int nest = 0, status = 0;
while (*p) {
@@ -2299,9 +2364,18 @@ ruby_brace_expand(const char *str, int flags, ruby_glob_func *func, VALUE arg,
if (lbrace && rbrace) {
size_t len = strlen(s) + 1;
- char *buf = GLOB_ALLOC_N(char, len);
+ char *buf;
long shift;
+ if (func == push_caller && !strchr(lbrace, '/')) {
+ /* Now it reaches file basename entry. */
+ /* Handle braces in glob_helper */
+ struct push_glob_args *a = (struct push_glob_args *)arg;
+ a->flags |= FNM_EXTGLOB;
+ return glob_call_func(func, s, arg, enc);
+ }
+
+ buf = GLOB_ALLOC_N(char, len);
if (!buf) return -1;
memcpy(buf, s, lbrace-s);
shift = (lbrace-s);
@@ -2365,12 +2439,6 @@ ruby_brace_glob(const char *str, int flags, ruby_glob_func *func, VALUE arg)
return ruby_brace_glob_with_enc(str, flags, func, arg, rb_ascii8bit_encoding());
}
-struct push_glob_args {
- struct glob_args glob;
- int flags;
- int fd;
-};
-
static int
push_caller(const char *path, VALUE val, void *enc)
{
</code></pre>
Ruby master - Bug #13852 (Closed): Backport r59693,59695 (Net::HTTP should raise error when CR/LF...
https://redmine.ruby-lang.org/issues/13852
2017-08-30T17:25:44Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>This is a ticket for backport management. The issue was already fixed on trunk.<br>
Let's treat r59693 as a bugfix and backport into stable branches.</p>
Ruby master - Feature #13712 (Closed): String#start_with? with regexp
https://redmine.ruby-lang.org/issues/13712
2017-07-04T09:18:51Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>String#start_with? should receive regexp.</p>
<p>When I write a parser, I want to check a string is start with a pattern or not.<br>
It's just the same thing with <a href="https://ruby-doc.org/stdlib-2.4.0/libdoc/strscan/rdoc/StringScanner.html#method-i-match-3F" class="external">StringScanner#match</a></p>
<p>If I want to do the same thing with normal string method, it needs to write like <code>/\A#{re}/.match(…)</code>.<br>
But if re is argument, it needs to create a new temporary regexp every time.</p>
<p>Though we have a workaround as follows but it's bit tricky.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"foo "</span><span class="p">.</span><span class="nf">rindex</span><span class="p">(</span><span class="sr">/fo+./</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</code></pre>
<p>A patch is following:</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/re.c b/re.c
index d0aa2a792e..f672ba75ec 100644
</span><span class="gd">--- a/re.c
</span><span class="gi">+++ b/re.c
</span><span class="p">@@ -1588,6 +1588,84 @@</span> rb_reg_search(VALUE re, VALUE str, long pos, int reverse)
return rb_reg_search0(re, str, pos, reverse, 1);
}
<span class="gi">+bool
+rb_reg_start_with_p(VALUE re, VALUE str)
+{
+ long pos = 0;
+ long result;
+ VALUE match;
+ struct re_registers regi, *regs = &regi;
+ regex_t *reg;
+ int tmpreg;
+ onig_errmsg_buffer err = "";
+
+ reg = rb_reg_prepare_re0(re, str, err);
+ tmpreg = reg != RREGEXP_PTR(re);
+ if (!tmpreg) RREGEXP(re)->usecnt++;
+
+ match = rb_backref_get();
+ if (!NIL_P(match)) {
+ if (FL_TEST(match, MATCH_BUSY)) {
+ match = Qnil;
+ }
+ else {
+ regs = RMATCH_REGS(match);
+ }
+ }
+ if (NIL_P(match)) {
+ MEMZERO(regs, struct re_registers, 1);
+ }
+ result = onig_match(reg,
+ (UChar*)(RSTRING_PTR(str)),
+ ((UChar*)(RSTRING_PTR(str)) + RSTRING_LEN(str)),
+ (UChar*)(RSTRING_PTR(str)),
+ regs, ONIG_OPTION_NONE);
+ if (!tmpreg) RREGEXP(re)->usecnt--;
+ if (tmpreg) {
+ if (RREGEXP(re)->usecnt) {
+ onig_free(reg);
+ }
+ else {
+ onig_free(RREGEXP_PTR(re));
+ RREGEXP_PTR(re) = reg;
+ }
+ }
+ if (result < 0) {
+ if (regs == &regi)
+ onig_region_free(regs, 0);
+ if (result == ONIG_MISMATCH) {
+ rb_backref_set(Qnil);
+ return false;
+ }
+ else {
+ onig_error_code_to_str((UChar*)err, (int)result);
+ rb_reg_raise(RREGEXP_SRC_PTR(re), RREGEXP_SRC_LEN(re), err, re);
+ }
+ }
+
+ if (NIL_P(match)) {
+ int err;
+ match = match_alloc(rb_cMatch);
+ err = rb_reg_region_copy(RMATCH_REGS(match), regs);
+ onig_region_free(regs, 0);
+ if (err) rb_memerror();
+ }
+ else {
+ FL_UNSET(match, FL_TAINT);
+ }
+
+ RMATCH(match)->str = rb_str_new4(str);
+ OBJ_INFECT(match, str);
+
+ RMATCH(match)->regexp = re;
+ RMATCH(match)->rmatch->char_offset_updated = 0;
+ rb_backref_set(match);
+
+ OBJ_INFECT(match, re);
+
+ return true;
+}
+
</span> VALUE
rb_reg_nth_defined(int nth, VALUE match)
{
<span class="gh">diff --git a/string.c b/string.c
index 072f1329ee..6542a4acb1 100644
</span><span class="gd">--- a/string.c
</span><span class="gi">+++ b/string.c
</span><span class="p">@@ -9126,6 +9126,7 @@</span> rb_str_rpartition(VALUE str, VALUE sep)
RSTRING_LEN(str)-pos-RSTRING_LEN(sep)));
}
<span class="gi">+extern bool rb_reg_start_with_p(VALUE re, VALUE str);
</span> /*
* call-seq:
* str.start_with?([prefixes]+) -> true or false
<span class="p">@@ -9146,11 +9147,20 @@</span> rb_str_start_with(int argc, VALUE *argv, VALUE str)
for (i=0; i<argc; i++) {
VALUE tmp = argv[i];
<span class="gd">- StringValue(tmp);
- rb_enc_check(str, tmp);
- if (RSTRING_LEN(str) < RSTRING_LEN(tmp)) continue;
- if (memcmp(RSTRING_PTR(str), RSTRING_PTR(tmp), RSTRING_LEN(tmp)) == 0)
- return Qtrue;
</span><span class="gi">+ switch (BUILTIN_TYPE(tmp)) {
+ case T_REGEXP:
+ {
+ bool r = rb_reg_start_with_p(tmp, str);
+ if (r) return Qtrue;
+ }
+ break;
+ default:
+ StringValue(tmp);
+ rb_enc_check(str, tmp);
+ if (RSTRING_LEN(str) < RSTRING_LEN(tmp)) continue;
+ if (memcmp(RSTRING_PTR(str), RSTRING_PTR(tmp), RSTRING_LEN(tmp)) == 0)
+ return Qtrue;
+ }
</span> }
return Qfalse;
}
</code></pre>
Ruby master - Feature #13608 (Rejected): Add TracePoint#thread
https://redmine.ruby-lang.org/issues/13608
2017-05-29T05:21:37Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>rb_trace_arg_t, TracePoint's internal struct, already stores the thread which the event happened at,<br>
but there's not API to fetch it.<br>
How about adding an API to get the info.</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb
index 53ee82a229..65dbc938ab 100644
</span><span class="gd">--- a/test/ruby/test_settracefunc.rb
</span><span class="gi">+++ b/test/ruby/test_settracefunc.rb
</span><span class="p">@@ -699,6 +699,23 @@</span> def test_tracepoint_enabled
assert_equal(false, trace.enabled?)
end
<span class="gi">+ def test_tracepoint_thread
+ trace = TracePoint.new(:call, :return){|tp|
+ next if !target_thread?
+ next if tp.path != __FILE__
+ assert_equal(Thread.current, tp.thread)
+ case tp.event
+ when :call
+ assert_raise(RuntimeError) {tp.return_value}
+ when :return
+ assert_equal("xyzzy", tp.return_value)
+ end
+ }
+ trace.enable{
+ foo
+ }
+ end
+
</span> def method_test_tracepoint_return_value obj
obj
end
<span class="gh">diff --git a/vm_trace.c b/vm_trace.c
index decb2c32e4..702b84e6e3 100644
</span><span class="gd">--- a/vm_trace.c
</span><span class="gi">+++ b/vm_trace.c
</span><span class="p">@@ -776,6 +776,12 @@</span> rb_tracearg_path(rb_trace_arg_t *trace_arg)
return trace_arg->path;
}
<span class="gi">+VALUE
+rb_tracearg_thread(rb_trace_arg_t *trace_arg)
+{
+ return trace_arg->th->self;
+}
+
</span> static void
fill_id_and_klass(rb_trace_arg_t *trace_arg)
{
<span class="p">@@ -913,6 +919,15 @@</span> tracepoint_attr_path(VALUE tpval)
}
/*
<span class="gi">+ * Thread of the event
+ */
+static VALUE
+tracepoint_attr_thread(VALUE tpval)
+{
+ return rb_tracearg_thread(get_trace_arg());
+}
+
+/*
</span> * Return the name at the definition of the method being called
*/
static VALUE
<span class="p">@@ -1502,6 +1517,7 @@</span> Init_vm_trace(void)
rb_define_method(rb_cTracePoint, "self", tracepoint_attr_self, 0);
rb_define_method(rb_cTracePoint, "return_value", tracepoint_attr_return_value, 0);
rb_define_method(rb_cTracePoint, "raised_exception", tracepoint_attr_raised_exception, 0);
<span class="gi">+ rb_define_method(rb_cTracePoint, "thread", tracepoint_attr_thread, 0);
</span>
rb_define_singleton_method(rb_cTracePoint, "stat", tracepoint_stat_s, 0);
</code></pre>
Ruby master - Bug #13304 (Closed): public function rb_thread_fd_close is removed at r57422
https://redmine.ruby-lang.org/issues/13304
2017-03-12T19:06:16Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>It hits abi-check:<br>
<a href="http://rubyci.org/logs/www.rubyist.net/~akr/chkbuild/debian/ruby-2.4/log/20170312T170653Z.log.html.gz#abi-check" class="external">http://rubyci.org/logs/www.rubyist.net/~akr/chkbuild/debian/ruby-2.4/log/20170312T170653Z.log.html.gz#abi-check</a></p>
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 - Bug #13150 (Closed): TestMarshal failures on FreeBSD with gcc7 because of GC
https://redmine.ruby-lang.org/issues/13150
2017-01-23T16:58:04Z
naruse (Yui NARUSE)
naruse@airemix.jp
<pre><code> 1) Failure:
TestMarshal#test_context_switch [/home/naruse/ruby/test/ruby/test_marshal.rb:368]:
[StopIteration] exception expected, not.
Class: <RuntimeError>
Message: <"Marshal.dump reentered at marshal_dump">
---Backtrace---
/home/naruse/ruby/test/ruby/test_marshal.rb:345:in `dump'
/home/naruse/ruby/test/ruby/test_marshal.rb:345:in `dump_each'
../../ruby/test/runner.rb: TestMarshal#test_context_switch:1:in `each'
---------------
2) Failure:
TestMarshal#test_gc [/home/naruse/ruby/test/ruby/test_marshal.rb:187]:
Exception raised:
<#<RuntimeError: Marshal.dump reentered at _dump>>.
Finished tests in 0.153251s, 698.2016 tests/s, 6238.1380 assertions/s.
107 tests, 956 assertions, 2 failures, 0 errors, 0 skips
ruby -v: ruby 2.5.0dev (2017-01-23 trunk 57407) [x86_64-freebsd10.3]
</code></pre>
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 - Feature #13020 (Closed): Zlib.gzip and Zlib.gunzip
https://redmine.ruby-lang.org/issues/13020
2016-12-09T22:37:22Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>I added Zlib.deflate/inflate [Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Add Zlib.deflate / Zlib.inflate (Closed)" href="https://redmine.ruby-lang.org/issues/4180">#4180</a>] before, but writing/reading gzip is still too complex.<br>
It should have shorthand method.</p>
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 - Feature #12896 (Closed): Add compiler version message into rbconfig
https://redmine.ruby-lang.org/issues/12896
2016-11-04T06:30:53Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>When a extension library developer receives bug reports, they sometimes want to know what compiler is used for building the ruby binary.<br>
We can already know its compiler option but cannot know compiler name and version.</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/configure.in b/configure.in
index 3734afa..6793d7d 100644
</span><span class="gd">--- a/configure.in
</span><span class="gi">+++ b/configure.in
</span><span class="p">@@ -536,8 +536,10 @@</span> for option in --version -v -V -qversion; do
AS_CASE($cc_version_status, [0], [:], [continue])
AS_CASE($cc_version_message, [*Warning*], [continue])
cc_version='$(CC) '$option
<span class="gi">+ break
</span> done
AC_SUBST(CC_VERSION, $cc_version)
<span class="gi">+AC_SUBST(CC_VERSION_MESSAGE, $cc_version_message)
</span><span class="err">
</span> RUBY_UNIVERSAL_ARCH
if test "$target_cpu" != "$host_cpu" -a "$GCC" = yes -a "$cross_compiling" = no -a "$universal_binary" = no; then
</code></pre>
Ruby master - Bug #12791 (Closed): Don't allow ,-separator for cookie
https://redmine.ruby-lang.org/issues/12791
2016-09-27T03:11:40Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>RFC2965 allowed both ; and , as a separator for cookie, but RFC6265 only allows ;.</p>
<p>Moreover CVE-2016-7401 uses , as a separator to overwrite CSRF-token.<br>
<a href="https://gist.github.com/mala/457a25650950d4daf4144f98159802cc" class="external">https://gist.github.com/mala/457a25650950d4daf4144f98159802cc</a></p>
Ruby master - Bug #12711 (Closed): Darwin doesn't show C backtrace correctly if iSIGSEGV is recei...
https://redmine.ruby-lang.org/issues/12711
2016-08-29T18:38:08Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Current Ruby can show C backtrace on the following case</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Process</span><span class="p">.</span><span class="nf">kill</span> <span class="ss">:SEGV</span><span class="p">,</span> <span class="vg">$$</span>
</code></pre>
<p>But can't on the following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span><span class="s2">"fiddle"</span>
<span class="no">Fiddle</span><span class="p">.</span><span class="nf">dlunwrap</span><span class="p">(</span><span class="mi">100</span><span class="p">).</span><span class="nf">class</span>
</code></pre>
Ruby master - Bug #12568 (Closed): wrong ArgumentError if an array is given for instance_exec wit...
https://redmine.ruby-lang.org/issues/12568
2016-07-07T18:50:32Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>From Ruby 2.2 to trunk, it wrongly raise ArgumentError as follows:</p>
<p>Sample code:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">instance_exec</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">]){</span><span class="o">|</span><span class="n">a</span><span class="o">|</span> <span class="nb">p</span> <span class="n">a</span><span class="p">}</span>
<span class="n">instance_exec</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">]){</span><span class="o">|</span><span class="n">a</span><span class="o">=</span><span class="p">[]</span><span class="o">|</span> <span class="nb">p</span> <span class="n">a</span><span class="p">}</span>
<span class="n">instance_exec</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">],</span> <span class="o">&-></span><span class="p">(</span><span class="n">a</span><span class="p">){</span> <span class="nb">p</span> <span class="n">a</span> <span class="p">})</span>
<span class="o">-></span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="p">[]){</span> <span class="nb">p</span> <span class="n">a</span> <span class="p">}.</span><span class="nf">to_proc</span><span class="p">.</span><span class="nf">call</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">])</span>
<span class="n">instance_exec</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">],</span> <span class="o">&-></span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="p">[]){</span> <span class="nb">p</span> <span class="n">a</span> <span class="p">})</span>
</code></pre>
<p>Expected result:</p>
<pre><code>[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
</code></pre>
<p>Actual result:</p>
<pre><code>[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
test.rb:7:in `block in <main>': wrong number of arguments (given 3, expected 0..1) (ArgumentError)
from test.rb:7:in `instance_exec'
from test.rb:7:in `<main>'
</code></pre>
<p>This issue affect <a href="https://github.com/rails/rails/pull/25699" class="external">https://github.com/rails/rails/pull/25699</a></p>
Ruby master - Bug #12563 (Closed): backport 49758,50356
https://redmine.ruby-lang.org/issues/12563
2016-07-06T20:40:07Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>49758,50356 is required to run <code>make test-rubyspec</code> because without them rubyspec fails to build option/capi/ext.<br>
<a href="https://travis-ci.org/ruby/ruby/builds/142788121" class="external">https://travis-ci.org/ruby/ruby/builds/142788121</a></p>
Ruby master - Bug #12560 (Closed): backport r55602
https://redmine.ruby-lang.org/issues/12560
2016-07-06T18:20:29Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>They may fail parallel test-all.</p>
<ul>
<li>ruby_2_3: <a href="https://travis-ci.org/ruby/ruby/builds/141708115" class="external">https://travis-ci.org/ruby/ruby/builds/141708115</a>
</li>
<li>ruby_2_2: <a href="https://travis-ci.org/ruby/ruby/builds/142772798" class="external">https://travis-ci.org/ruby/ruby/builds/142772798</a>
</li>
</ul>
Ruby master - Feature #12553 (Closed): IO.readlines(filename, chomp: true)
https://redmine.ruby-lang.org/issues/12553
2016-07-05T09:11:11Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>IO.readlinesやIO.foreach、IO#each_lineなどは戻り値(またはブロックパラメータ)のそれぞれの「行」に改行を含みます。</p>
<p>POSIXの "Line" の定義は末尾の改行を含んでのものなので非常に正しい挙動なのですが、正直不便です。</p>
<blockquote>
<p><a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206" class="external">3.206 Line</a></p>
<p>A sequence of zero or more non- characters plus a terminating character.</p>
</blockquote>
<p>例えば IO.readlines(filename, chomp: true) などで改行を最初から削ってくれませんか</p>
Ruby master - Misc #12474 (Third Party's Issue): Wishlist for Windows Unix compatibility features
https://redmine.ruby-lang.org/issues/12474
2016-06-09T08:37:29Z
naruse (Yui NARUSE)
naruse@airemix.jp
<a name="fork2"></a>
<h2 >fork(2)<a href="#fork2" class="wiki-anchor">¶</a></h2>
<p>Windows already has related features like <code>CreateProcess</code>, but for servers and workers fork is required for source code compatibility of existing scripts,<br>
which are written for Unix.</p>
<a name="nonblocking-IO"></a>
<h2 >nonblocking IO<a href="#nonblocking-IO" class="wiki-anchor">¶</a></h2>
<ul>
<li>To check socket's availability by <code>IO#read_nonblock</code> <a href="https://github.com/ruby/ruby/pull/1089" class="external">https://github.com/ruby/ruby/pull/1089</a>
</li>
<li><code>O_NONBLOCK</code></li>
</ul>
<a name="Signal"></a>
<h2 >Signal<a href="#Signal" class="wiki-anchor">¶</a></h2>
<p>Windows doesn't support true Signal.<br>
<a href="https://msdn.microsoft.com/en-us//library/xdkz3x12.aspx" class="external">https://msdn.microsoft.com/en-us//library/xdkz3x12.aspx</a></p>
<a name="tz"></a>
<h2 >tz<a href="#tz" class="wiki-anchor">¶</a></h2>
<p>Get IANA timezone name of current timezone from OS.</p>
<a name="Remove-a-file-which-is-opened-by-another-process"></a>
<h2 >Remove a file which is opened by another process<a href="#Remove-a-file-which-is-opened-by-another-process" class="wiki-anchor">¶</a></h2>
<p>If the process opens the file with <code>CreateFile</code> with <code>FILE_SHARE_DELETE</code> flag, another process can remove the file.<br>
But in that case processes can't remove its parent folder.<br>
<a href="https://bugs.ruby-lang.org/issues/11218" class="external">https://bugs.ruby-lang.org/issues/11218</a></p>
<a name="symlink"></a>
<h2 >symlink<a href="#symlink" class="wiki-anchor">¶</a></h2>
<p>Windows has mklink and SeCreateSymbolicLinkPrivilege, but it has some limitations.<br>
<a href="http://k-takata.o.oo7.jp/diary/2013-04.html#03" class="external">http://k-takata.o.oo7.jp/diary/2013-04.html#03</a><br>
<a href="https://twitter.com/n0kada/status/570232516545638400" class="external">https://twitter.com/n0kada/status/570232516545638400</a></p>
<a name="Bug-18882-On-64-mingw-ucrt-Fileread-sometimes-doesnt-read-entire-file-alanwu"></a>
<h2 >[Bug <a class="issue tracker-1 status-6 priority-4 priority-default closed" title="Bug: File.read cuts off a text file with special characters when reading it on MS Windows (Rejected)" href="https://redmine.ruby-lang.org/issues/18882">#18882</a>] On 64-mingw-ucrt, File.read() sometimes doesn't read entire file (alanwu)<a href="#Bug-18882-On-64-mingw-ucrt-Fileread-sometimes-doesnt-read-entire-file-alanwu" class="wiki-anchor">¶</a></h2>
<p><a href="https://github.com/ruby/dev-meeting-log/blob/master/DevMeeting-2022-07-21.md#bug-18882-on-64-mingw-ucrt-fileread-sometimes-doesnt-read-entire-file-alanwu" class="external">https://github.com/ruby/dev-meeting-log/blob/master/DevMeeting-2022-07-21.md#bug-18882-on-64-mingw-ucrt-fileread-sometimes-doesnt-read-entire-file-alanwu</a></p>
<a name="fd"></a>
<h2 >fd<a href="#fd" class="wiki-anchor">¶</a></h2>
<a name="Generic-handling-of-file-pipe-socket-by-fd"></a>
<h3 >Generic handling of file, pipe, socket by fd<a href="#Generic-handling-of-file-pipe-socket-by-fd" class="wiki-anchor">¶</a></h3>
<a name="fd-passing-to-child-process-other-than-012"></a>
<h3 >fd passing to child process other than 0,1,2<a href="#fd-passing-to-child-process-other-than-012" class="wiki-anchor">¶</a></h3>
<a name="Get-access-mode-from-fdHANDLE"></a>
<h3 >Get access mode from fd/HANDLE<a href="#Get-access-mode-from-fdHANDLE" class="wiki-anchor">¶</a></h3>
<a name="System-side-append-mode"></a>
<h3 >System side append mode<a href="#System-side-append-mode" class="wiki-anchor">¶</a></h3>
<p><a href="https://bugs.ruby-lang.org/issues/18605" class="external">https://bugs.ruby-lang.org/issues/18605</a></p>
<a name="a-high-performance-selector-API"></a>
<h3 >a high performance selector API<a href="#a-high-performance-selector-API" class="wiki-anchor">¶</a></h3>
<p><a href="https://tonyarcieri.com/a-gentle-introduction-to-nio4r" class="external">https://tonyarcieri.com/a-gentle-introduction-to-nio4r</a></p>
<a name="socket"></a>
<h2 >socket<a href="#socket" class="wiki-anchor">¶</a></h2>
<p><code>CloseHandle</code> should work with socket.</p>
<a name="writev2"></a>
<h2 >writev(2)<a href="#writev2" class="wiki-anchor">¶</a></h2>
<p><a href="https://twitter.com/okuoku/status/670212493134852097" class="external">https://twitter.com/okuoku/status/670212493134852097</a><br>
<a href="https://msdn.microsoft.com/ja-jp/library/windows/desktop/aa365749%28v=vs.85%29.aspx" class="external">https://msdn.microsoft.com/ja-jp/library/windows/desktop/aa365749%28v=vs.85%29.aspx</a></p>
<a name="ANSI-color-code"></a>
<h2 >ANSI color code<a href="#ANSI-color-code" class="wiki-anchor">¶</a></h2>
<p><a href="http://srad.jp/story/16/02/09/0639223/" class="external">http://srad.jp/story/16/02/09/0639223/</a></p>
<a name="UNIXSocket"></a>
<h2 ><del>UNIXSocket</del><a href="#UNIXSocket" class="wiki-anchor">¶</a></h2>
<p><del>We can emuate UNIXSocket with named pipe?</del><br>
Implemented [Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Support `UNIXSocket` on Windows (Closed)" href="https://redmine.ruby-lang.org/issues/19135">#19135</a>]</p>
Ruby master - Feature #12336 (Closed): Use -std=gnu99 instead of -std=c99 for GCC
https://redmine.ruby-lang.org/issues/12336
2016-05-01T09:58:53Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>r36038以降、Ruby本体をビルドする際にはGCCに-stdオプションを与えており、<br>
若干の変更を経て現在では-std=iso9899:1999 (-std=c99相当)を指定しています。</p>
<p>しかしこの指定の場合、GCCのC標準関数の代わりにビルトイン関数を用いる最適化が行われないため、<br>
現在ちょっと残念な状態が続いています。<br>
<a href="https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html" class="external">https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html</a></p>
<p>また、これの導入のきっかけはおそらくr36029の</p>
<ul>
<li>compile.c (iseq_set_sequence): nonstatic initializer of an aggregate type is a C99ism.</li>
<li>compile.c (enum compile_array_type_t): comma at the end of enum list is a C99ism.</li>
</ul>
<p>だと思うのですが、すでにc99相当なのであんまり効いてない……かな?<br>
もっともやりがちなMixed Declarationsは別に-Wdeclaration-after-statementがあるのでそれはそれで問題ありません。<br>
<a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html" class="external">https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html</a><br>
<a href="https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html" class="external">https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html</a></p>
<p>現在だと、-std=gnu99でおおむね同レベルの警告を維持できると同時に、<br>
GCCのビルトイン関数を使えるようになってわずかな手間でちょっと早くなって嬉しいと思うのですがいかがでしょう。</p>
Ruby master - Bug #12320 (Closed): Skip SHA from test_digest_constants for LibreSSL 2.3
https://redmine.ruby-lang.org/issues/12320
2016-04-26T06:30:04Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Backport r53718 to fix the first one of ruby/openssl#40<br>
<a href="https://github.com/ruby/openssl/issues/40#issuecomment-159839338" class="external">https://github.com/ruby/openssl/issues/40#issuecomment-159839338</a></p>
Ruby master - Bug #12316 (Third Party's Issue): clang on Linux wrongly keep the inlined symbol
https://redmine.ruby-lang.org/issues/12316
2016-04-24T14:56:35Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Through clang-3.4 to clang-3.8 they wrongly keep the inlined symbols, and it cause compilation error.</p>
<pre><code>compiling vm.c
linking miniruby
vm.o: In function `vm_getinstancevariable':
/home/naruse/ruby-clang/./vm_insnhelper.c:876: undefined reference to `vm_getivar'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Makefile:223: recipe for target 'miniruby' failed
make: *** [miniruby] Error 1
</code></pre>
<p>Note that Apple's and FreeBSD's following versions works fine.</p>
<pre><code>Apple LLVM version 7.3.0 (clang-703.0.29)
Target: x86_64-apple-darwin15.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
FreeBSD clang version 3.4.1 (tags/RELEASE_34/dot1-final 208032) 20140512
Target: x86_64-unknown-freebsd10.3
Thread model: posix
</code></pre>
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 #12225 (Rejected): Remove inline assemblers and always enables USE_MACHINE_...
https://redmine.ruby-lang.org/issues/12225
2016-03-28T08:20:39Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Current vm_exec.c stores pc an explicitly declared register to get PC.<br>
Since recent CPUs and compilers are very smart, we expect they optimizes their use of registers.</p>
<p>With following patch the benchmark becomes following:</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/vm_exec.c b/vm_exec.c
index 5e4ff94..6f7c1ad 100644
</span><span class="gd">--- a/vm_exec.c
</span><span class="gi">+++ b/vm_exec.c
</span><span class="p">@@ -15,23 +15,6 @@</span>
static void vm_analysis_insn(int insn);
#endif
<span class="gd">-#if VMDEBUG > 0
-#define DECL_SC_REG(type, r, reg) register type reg_##r
-
-#elif defined(__GNUC__) && defined(__x86_64__)
-#define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("r" reg)
-
-#elif defined(__GNUC__) && defined(__i386__)
-#define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("e" reg)
-
-#elif defined(__GNUC__) && defined(__powerpc64__)
-#define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("r" reg)
-
-#else
-#define DECL_SC_REG(type, r, reg) register type reg_##r
-#endif
-/* #define DECL_SC_REG(r, reg) VALUE reg_##r */
-
</span> #if VM_DEBUG_STACKOVERFLOW
NORETURN(static void vm_stack_overflow_for_insn(void));
static void
<span class="p">@@ -49,41 +32,12 @@</span> vm_exec_core(rb_thread_t *th, VALUE initial)
{
#if OPT_STACK_CACHING
<span class="gd">-#if 0
-#elif __GNUC__ && __x86_64__ && !defined(__native_client__)
- DECL_SC_REG(VALUE, a, "12");
- DECL_SC_REG(VALUE, b, "13");
-#else
</span> register VALUE reg_a;
register VALUE reg_b;
#endif
<span class="gd">-#endif
</span>
<span class="gd">-#if defined(__GNUC__) && defined(__i386__)
- DECL_SC_REG(const VALUE *, pc, "di");
- DECL_SC_REG(rb_control_frame_t *, cfp, "si");
-#define USE_MACHINE_REGS 1
-
-#elif defined(__GNUC__) && defined(__x86_64__)
- DECL_SC_REG(const VALUE *, pc, "14");
-# if defined(__native_client__)
- DECL_SC_REG(rb_control_frame_t *, cfp, "13");
-# else
- DECL_SC_REG(rb_control_frame_t *, cfp, "15");
-# endif
-#define USE_MACHINE_REGS 1
-
-#elif defined(__GNUC__) && defined(__powerpc64__)
- DECL_SC_REG(const VALUE *, pc, "14");
- DECL_SC_REG(rb_control_frame_t *, cfp, "15");
-#define USE_MACHINE_REGS 1
-
-#else
</span> register rb_control_frame_t *reg_cfp;
const VALUE *reg_pc;
<span class="gd">-#endif
-
-#if USE_MACHINE_REGS
</span>
#undef RESTORE_REGS
#define RESTORE_REGS() \
<span class="p">@@ -98,7 +52,6 @@</span> vm_exec_core(rb_thread_t *th, VALUE initial)
#define GET_PC() (reg_pc)
#undef SET_PC
#define SET_PC(x) (reg_cfp->pc = REG_PC = (x))
<span class="gd">-#endif
</span>
#if OPT_TOKEN_THREADED_CODE || OPT_DIRECT_THREADED_CODE
#include "vmtc.inc"
</code></pre>
<pre><code>Speedup ratio: compare with the result of `ruby 2.4.0dev (2016-03-27 trunk 54303) [x86_64-linux]' (greater is better)
name built-ruby
loop_whileloop 1.016
vm1_attr_ivar* 0.991
vm1_attr_ivar_set* 0.976
vm1_block* 1.013
vm1_const* 0.924
vm1_ensure* 0.978
vm1_float_simple* 1.006
vm1_gc_short_lived* 1.011
vm1_gc_short_with_complex_long* 1.036
vm1_gc_short_with_long* 1.064
vm1_gc_short_with_symbol* 0.997
vm1_gc_wb_ary* 1.005
vm1_gc_wb_ary_promoted* 1.000
vm1_gc_wb_obj* 0.977
vm1_gc_wb_obj_promoted* 1.029
vm1_ivar* 1.054
vm1_ivar_set* 0.961
vm1_length* 1.019
vm1_lvar_init* 0.962
vm1_lvar_set* 0.991
vm1_neq* 0.976
vm1_not* 0.903
vm1_rescue* 0.983
vm1_simplereturn* 1.005
vm1_swap* 1.000
vm1_yield* 0.979
</code></pre>
<pre><code>additional example micro benchmark
BEFORE gcc 4.8:
Performance counter stats for './miniruby -e@v=42; n=100_000_000;while n>0; x=x|x; x=x|x;n-=1;end':
7218.124555 task-clock (msec) # 0.998 CPUs utilized
123 context-switches # 0.017 K/sec
2 cpu-migrations # 0.000 K/sec
906 page-faults # 0.126 K/sec
21374094581 cycles # 2.961 GHz
4469895839 stalled-cycles-frontend # 20.91% frontend cycles idle
<not supported> stalled-cycles-backend
55226298374 instructions # 2.58 insns per cycle
# 0.08 stalled cycles per insn
7805291103 branches # 1081.346 M/sec
200172514 branch-misses # 2.56% of all branches
7.230608341 seconds time elapsed
BEFORE gcc version 5.3.0 20151204 (Ubuntu 5.3.0-3ubuntu1~14.04):
Performance counter stats for './miniruby -e@v=42; n=100_000_000;while n>0; x=x|x; x=x|x;n-=1;end':
8054.736236 task-clock (msec) # 0.998 CPUs utilized
128 context-switches # 0.016 K/sec
2 cpu-migrations # 0.000 K/sec
895 page-faults # 0.111 K/sec
23776261112 cycles # 2.952 GHz
7078686240 stalled-cycles-frontend # 29.77% frontend cycles idle
<not supported> stalled-cycles-backend
53126508523 instructions # 2.23 insns per cycle
# 0.13 stalled cycles per insn
7505454893 branches # 931.806 M/sec
201181233 branch-misses # 2.68% of all branches
8.074872624 seconds time elapsed
AFTER gcc version 4.8.5 (Ubuntu 4.8.5-2ubuntu1~14.04.1):
Performance counter stats for './miniruby -e@v=42; n=100_000_000;while n>0; x=x|x; x=x|x;n-=1;end':
7267.867318 task-clock (msec) # 0.997 CPUs utilized
169 context-switches # 0.023 K/sec
1 cpu-migrations # 0.000 K/sec
899 page-faults # 0.124 K/sec
21563673390 cycles # 2.967 GHz
4952119471 stalled-cycles-frontend # 22.97% frontend cycles idle
<not supported> stalled-cycles-backend
53226715304 instructions # 2.47 insns per cycle
# 0.09 stalled cycles per insn
7805365852 branches # 1073.955 M/sec
200218594 branch-misses # 2.57% of all branches
7.286793973 seconds time elapsed
AFTER gcc version 5.3.0 20151204 (Ubuntu 5.3.0-3ubuntu1~14.04):
Performance counter stats for './miniruby -e@v=42; n=100_000_000;while n>0; x=x|x; x=x|x;n-=1;end':
7146.899779 task-clock (msec) # 0.998 CPUs utilized
166 context-switches # 0.023 K/sec
2 cpu-migrations # 0.000 K/sec
899 page-faults # 0.126 K/sec
21188099959 cycles # 2.965 GHz
4839187155 stalled-cycles-frontend # 22.84% frontend cycles idle
<not supported> stalled-cycles-backend
52525802838 instructions # 2.48 insns per cycle
# 0.09 stalled cycles per insn
7505329721 branches # 1050.152 M/sec
200175714 branch-misses # 2.67% of all branches
7.157645157 seconds time elapsed
</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 - Bug #12158 (Closed): Fixnum#% doesn't show its name on ZeroDivisionError
https://redmine.ruby-lang.org/issues/12158
2016-03-08T08:54:05Z
naruse (Yui NARUSE)
naruse@airemix.jp
<pre><code>% ruby -ve'p 12345 % 0'
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-freebsd10.2]
-e:1:in `<main>': divided by 0 (ZeroDivisionError)
</code></pre>
<p>It should behave like</p>
<pre><code>% ruby -ve'p 12345 / 0'
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-freebsd10.2]
-e:1:in `/': divided by 0 (ZeroDivisionError)
from -e:1:in `<main>'
</code></pre>
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 - Bug #12011 (Closed): honor Marshal.load post proc value for TYPE_LINK
https://redmine.ruby-lang.org/issues/12011
2016-01-20T02:25:15Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Following test doesn't work.<br>
A patch also attached.<br>
Both of them are worked by nahi.</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/test/ruby/test_marshal.rb b/test/ruby/test_marshal.rb
index 482637f..262e7f6 100644
</span><span class="gd">--- a/test/ruby/test_marshal.rb
</span><span class="gi">+++ b/test/ruby/test_marshal.rb
</span><span class="p">@@ -712,4 +712,10 @@</span> def test_no_internal_ids
assert_predicate(status, :success?)
assert_equal(expected, out)
end
<span class="gi">+
+ def test_marshal_post_proc
+ str = 'x' # for link
+ obj = [str, str]
+ assert_equal(['X', 'X'], Marshal.load(Marshal.dump(obj), ->(v) { v == str ? v.upcase : v }))
+ end
</span> end
<span class="gh">diff --git a/marshal.c b/marshal.c
index d67ce87..d64e5ff 100644
</span><span class="gd">--- a/marshal.c
</span><span class="gi">+++ b/marshal.c
</span><span class="p">@@ -1569,7 +1569,7 @@</span> r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
rb_raise(rb_eArgError, "dump format error (unlinked)");
}
v = (VALUE)link;
<span class="gd">- r_post_proc(v, arg);
</span><span class="gi">+ v = r_post_proc(v, arg);
</span> break;
case TYPE_IVAR:
</code></pre>
<p><a href="https://github.com/ruby/ruby/pull/1204" class="external">https://github.com/ruby/ruby/pull/1204</a></p>
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 - Bug #11613 (Closed): test_aspawn_too_long_path creates too many processes
https://redmine.ruby-lang.org/issues/11613
2015-10-22T16:52:33Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>At least on FreeBSD, spawn("echo|echo|echo|echo|echo|echo|echo| ...20000 times") success and create 20000 zombie processes.<br>
To prevent this you can add rlimit_nproc: 1 because it tests sh itself, don't test spawned echos.</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb
index 32dcaed..7877171 100644
</span><span class="gd">--- a/test/ruby/test_process.rb
</span><span class="gi">+++ b/test/ruby/test_process.rb
</span><span class="p">@@ -1600,7 +1600,7 @@</span> class TestProcess < Test::Unit::TestCase
assert_raise(*exs, mesg) do
begin
loop do
<span class="gd">- Process.spawn(cmds.join(sep), [STDOUT, STDERR]=>File::NULL)
</span><span class="gi">+ Process.spawn(cmds.join(sep), [STDOUT, STDERR]=>File::NULL, rlimit_nproc: 1)
</span> min = [cmds.size, min].max
cmds *= 100
end
</code></pre>
Ruby master - Feature #11558 (Closed): Time related C APIs
https://redmine.ruby-lang.org/issues/11558
2015-09-30T05:59:44Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Time関連のC APIを追加して欲しいです。<br>
具体的には以下のようなものが欲しいです。</p>
<p>struct timespecとoffsetを取って、Timeを返してください。<br>
VALUE rb_time_timespec_new(const struct timespec *ts, int offset);<br>
趣旨としては、[秒, ナノ秒, offset]からTimeを作って欲しいと言うことです。<br>
(rb_time_num_new(Rational, offset)とかだと手間かかる上に遅い)</p>
<p>現在時刻をstruct timespecで欲しいです。<br>
void timespec_now(struct timespec *ts);</p>
<p>既存の非公開APIを公開してください。<br>
struct tm * localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long *gmtoff, const char **zone);<br>
time_t timegm_noleapsecond(struct tm *tm);<br>
void tm_add_offset(struct tm *tm, long diff);</p>
<p><a href="https://github.com/nurse/strptime/blob/v0.1.1/ext/strptime/ruby_time.c" class="external">https://github.com/nurse/strptime/blob/v0.1.1/ext/strptime/ruby_time.c</a></p>
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 - Bug #11457 (Closed): miniruby SEGVs on CentOS 5
https://redmine.ruby-lang.org/issues/11457
2015-08-18T11:03:58Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>minirubyがCentOS 5 (64bit) でSEGVするやつです。<br>
<a href="http://rubyci.s3.amazonaws.com/centos5-64/ruby-trunk/log/20150818T093302Z.log.html.gz#miniversion" class="external">http://rubyci.s3.amazonaws.com/centos5-64/ruby-trunk/log/20150818T093302Z.log.html.gz#miniversion</a></p>
<p>パッチ見ればわかりますが原因はr49452です。<br>
2.1と2.2にはバックポートされているようだけど、2.0.0には入っていないと思う。</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 - Feature #11251 (Closed): Thread#name and Thread#name=
https://redmine.ruby-lang.org/issues/11251
2015-06-12T02:48:43Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Threadの名前の取得・設定を行うAPIを追加しませんか。</p>
<p><a class="issue tracker-2 status-2 priority-4 priority-default" title="Feature: Thread.new without block. (Assigned)" href="https://redmine.ruby-lang.org/issues/6694">#6694</a> や <a class="issue tracker-2 status-2 priority-4 priority-default" title="Feature: Configuration for Thread/Fiber creation (Assigned)" href="https://redmine.ruby-lang.org/issues/6695">#6695</a> などで断続的に議論がなされ、r47670 で一部自動で名前が付けられるようになったりもしていますが、<br>
Rubyレベルでそれを見る手段は提供されていませんし、明示的に付けることも出来ません。</p>
<p>今でもニーズは結構あるようです。</p>
<blockquote>
<p>"Fluentdでどのスレッドがどのプラグインに属しているのかが簡単に分かるようになるんですよね”<br>
<a href="https://twitter.com/repeatedly/status/608855851131011073" class="external">https://twitter.com/repeatedly/status/608855851131011073</a><br>
"確かにRubyのスレッドに名前付けられたら良さそう。主にログで識別する用途で。"<br>
<a href="https://twitter.com/frsyuki/status/608863065598140417" class="external">https://twitter.com/frsyuki/status/608863065598140417</a></p>
</blockquote>
<pre><code>Linux (glibc 2.12+)
int pthread_setname_np(pthread_t thread, const char *name);
int pthread_getname_np(pthread_t thread, char *name, size_t len);
FreeBSD
void pthread_set_name_np(pthread_t, const char *);
NetBSD
int pthread_getname_np(pthread_t thread, char *name, size_t len);
int pthread_setname_np(pthread_t thread, const char *name, void *arg);
http://netbsd.gw.com/cgi-bin/man-cgi?pthread_setname_np++NetBSD-current
OS X
/usr/include/pthread/pthread.h:int pthread_getname_np(pthread_t,char*,size_t);
/usr/include/pthread/pthread.h:int pthread_setname_np(const char*);
</code></pre>
Ruby master - Feature #11220 (Rejected): strptime(%6N)
https://redmine.ruby-lang.org/issues/11220
2015-06-04T14:46:35Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>strftimeにはマイクロ秒などでの出力を指定する、%6N, %9Nというフォーマットがあります。<br>
一方で、パースを行うstrptimeにはそのような指定子が現在ありません。</p>
<p>そのようなものに対するニーズはぼちぼちあるようなので入れませんか。<br>
<a href="http://answers.splunk.com/answers/1946/time-format-and-subseconds.html" class="external">http://answers.splunk.com/answers/1946/time-format-and-subseconds.html</a><br>
<a href="https://twitter.com/nalsh/status/606414387352502272" class="external">https://twitter.com/nalsh/status/606414387352502272</a></p>
<pre><code>diff --git a/ext/date/date_strptime.c b/ext/date/date_strptime.c
index e318af1..89a6421 100644
--- a/ext/date/date_strptime.c
+++ b/ext/date/date_strptime.c
@@ -611,6 +611,33 @@ date__strptime_internal(const char *str, size_t slen,
recur("%a %b %e %H:%M:%S %Z %Y");
goto matched;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ {
+ VALUE n;
+ size_t w;
+ int sign = 1;
+ size_t osi;
+ w = read_digits(&fmt[fi], &n, 1);
+ fi += w;
+ w = NUM2SIZET(n);
+
+ if (issign(str[si])) {
+ if (str[si] == '-')
+ sign = -1;
+ si++;
+ }
+ osi = si;
+ READ_DIGITS(n, w == 0 ? 9 : w)
+ if (sign == -1)
+ n = f_negate(n);
+ set_hash("sec_fraction",
+ rb_rational_new2(n,
+ f_expt(INT2FIX(10),
+ ULONG2NUM(si - osi))));
+ goto matched;
+ }
+
default:
if (str[si] != '%')
fail();
</code></pre>
Ruby master - Feature #11218 (Closed): File.open FILE_SHARE_DELETE
https://redmine.ruby-lang.org/issues/11218
2015-06-04T05:19:41Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>fluentdという、OSSのログコレクタがあるのですが、これには<code>in_tail</code>プラグインというものがあります。<br>
これは、ログファイルを監視して、ログがファイルに追記されたらその分を読み込んでJSONにして他に流します。</p>
<p>このログファイルはfluentdではない他の誰か、ApacheだったりRailsだったりします。<br>
この手のログファイルを書いていく流儀はいくつかありますが、ご存じの通りRailsやApacheは基本的に特定のパスにひたすら追記し続け、<br>
それでは肥大化しすぎるのでlogrotateなどと組み合わせて適宜rotateしていく運用が一般的でしょう。<br>
つまり、ログファイルをrenameし、ApacheやRailsなどにsignalで再起動して新しいファイルに書くわけです。</p>
<p>ところで、Windowsは誰かが開いているファイルをrenameすることはできないので通常このようなことは出来ません。<br>
やるにはファイルを開く際の<code>CreateFile</code>に<code>FILE_SHARE_DELETE</code>フラッグをつけてやる必要があります。<br>
そんなことやってる人いるのかというご指摘もあるとは思いますが、やる人はやっているようです。<br>
<a href="https://issues.apache.org/jira/browse/HADOOP-8564" class="external">https://issues.apache.org/jira/browse/HADOOP-8564</a></p>
<p>さて、RubyのWindowsの<code>open(2)</code>ラッパー、<code>rb_w32_open</code>/<code>rb_w32_wopen</code>はテキストモードの場合は<code>_open</code>/<code>_wopen</code>を使っており、<br>
これはおいておくとして、バイナリモードの場合は<code>CreateFile</code>を使っているものの現状<code>FILE_SHARE_DELETE</code>は渡していないので、<br>
なんらかの手段で<code>FILE_SHARE_DELETE</code>を付けられるようになりませんか。</p>
Ruby master - Feature #11216 (Closed): inode for Windows
https://redmine.ruby-lang.org/issues/11216
2015-06-03T13:32:22Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>現在WindowsではFile::Stat#inodeは常に0を返しますが、<br>
例えばあるlogrotate的な運用の行われるファイルを監視・開きっぱなしにして、追記されれば差分を読み、<br>
rotateされた場合は検出して最新のログを読む…というような場合に、rotateを検出する際にinodeは使われます。</p>
<p>WindowsにはGetFileInformationByHandle()というAPIで得られるBY_HANDLE_FILE_INFORMATION構造体のメンバ、<br>
nFileIndexHigh/Lowから64bitのファイルシステムuniqueなIDがあるので、これをinodeとして代用が可能です。</p>
<p>問題はこれをFile::Statにいれるにはもとのstruct stat.inoが16bitで小さすぎる点ですが、<br>
幸いstruct stati64にはアライメントの都合で隙間があるため、そこにつっこむことにしています。<br>
(devとudevが常に同じとか、uidやgidが常に0など無意味な値は他にもありますが)<br>
<a href="https://msdn.microsoft.com/ja-jp/library/ms350241%28v=vs.71%29.aspx" class="external">https://msdn.microsoft.com/ja-jp/library/ms350241%28v=vs.71%29.aspx</a></p>
<pre><code>diff --git a/file.c b/file.c
index ac99de6..761ff1f 100644
--- a/file.c
+++ b/file.c
@@ -548,7 +548,18 @@ rb_stat_dev_minor(VALUE self)
static VALUE
rb_stat_ino(VALUE self)
{
-#if SIZEOF_STRUCT_STAT_ST_INO > SIZEOF_LONG
+#ifdef _WIN32
+ struct stat *st = get_stat(self);
+ unsigned short *p2 = (unsigned short *)st;
+ unsigned int *p4 = (unsigned int *)st;
+ uint64_t r;
+ r = p2[2];
+ r <<= 16;
+ r |= p2[7];
+ r <<= 32;
+ r |= p4[5];
+ return ULL2NUM(r);
+#elif SIZEOF_STRUCT_STAT_ST_INO > SIZEOF_LONG
return ULL2NUM(get_stat(self)->st_ino);
#else
return ULONG2NUM(get_stat(self)->st_ino);
diff --git a/win32/win32.c b/win32/win32.c
index b23e9af..fcfc0a6 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -4975,6 +4975,48 @@ static time_t filetime_to_unixtime(const FILETIME *ft);
static WCHAR *name_for_stat(WCHAR *buf, const WCHAR *path);
static DWORD stati64_handle(HANDLE h, struct stati64 *st);
+/* License: Ruby's */
+static void
+stati64_set_inode(PBY_HANDLE_FILE_INFORMATION pinfo, struct stati64 *st)
+{
+ /* struct stati64 layout
+ *
+ * dev: 0-3
+ * ino: 4-5
+ * mode: 6-7
+ * nlink: 8-9
+ * uid: 10-11
+ * gid: 12-13
+ * _: 14-15
+ * rdev: 16-19
+ * _: 20-23
+ * size: 24-31
+ * atime: 32-39
+ * mtime: 40-47
+ * ctime: 48-55
+ *
+ */
+ unsigned short *p2 = (unsigned short *)st;
+ unsigned int *p4 = (unsigned int *)st;
+ DWORD high = pinfo->nFileIndexHigh;
+ p2[2] = high >> 16;
+ p2[7] = high & 0xFFFF;
+ p4[5] = pinfo->nFileIndexLow;
+}
+
+/* License: Ruby's */
+static DWORD
+stati64_set_inode_handle(HANDLE h, struct stati64 *st)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ DWORD attr = (DWORD)-1;
+
+ if (GetFileInformationByHandle(h, &info)) {
+ stati64_set_inode(&info, st);
+ }
+ return attr;
+}
+
#undef fstat
/* License: Ruby's */
int
@@ -5000,7 +5042,11 @@ rb_w32_fstati64(int fd, struct stati64 *st)
struct stat tmp;
int ret;
- if (GetEnvironmentVariableW(L"TZ", NULL, 0) == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) return _fstati64(fd, st);
+ if (GetEnvironmentVariableW(L"TZ", NULL, 0) == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
+ ret = _fstati64(fd, st);
+ stati64_set_inode_handle((HANDLE)_get_osfhandle(fd), st);
+ return ret;
+ }
ret = fstat(fd, &tmp);
if (ret) return ret;
@@ -5022,6 +5068,7 @@ stati64_handle(HANDLE h, struct stati64 *st)
st->st_mtime = filetime_to_unixtime(&info.ftLastWriteTime);
st->st_ctime = filetime_to_unixtime(&info.ftCreationTime);
st->st_nlink = info.nNumberOfLinks;
+ stati64_set_inode(&info, st);
attr = info.dwFileAttributes;
}
return attr;
</code></pre>
Ruby master - Bug #11206 (Closed): short file name match incompatibility
https://redmine.ruby-lang.org/issues/11206
2015-06-01T17:54:57Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>When I develop a foo.gem, my working diretory has foo.gemspec and foo.gem.<br>
If I run <code>gem install -l foo</code>, it fails as following:</p>
<p>ERROR: While executing gem ... (Gem::Package::FormatError)<br>
package metadata is missing in foo.gemspec</p>
<p>Because gem command tries to traverse the current directory with Dir["*.gem"],<br>
and it include *.gemspec.</p>
<p>Another example, Rakefile has <code>rake clean</code> task and it is specified by CLEAN constant.<br>
if I specify CLEAN.include( "*.gem" ), it removes *.gemspec.</p>
Ruby master - Bug #11172 (Closed): Windowsでmode: ab+の時に開いたファイルの内容が読めない
https://redmine.ruby-lang.org/issues/11172
2015-05-23T15:23:47Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Windowsでopen("hoge.txt", "ab+")すると、開いたファイルの既存の内容が読めません。<br>
File::APPEND|File::CREAT|File::RDWR|File::BINARYでも同様です。</p>
<p>Unixでは読める上に、a+の時、つまり_openを使う場合も読めるので、意図しない挙動でしょう。</p>
<pre><code>diff --git a/win32/win32.c b/win32/win32.c
index 55e0d2e..57d9df4 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -6476,12 +6476,16 @@ rb_w32_close(int fd)
}
static int
-setup_overlapped(OVERLAPPED *ol, int fd)
+setup_overlapped(OVERLAPPED *ol, int fd, int iswrite)
{
memset(ol, 0, sizeof(*ol));
if (!(_osfile(fd) & (FDEV | FPIPE))) {
LONG high = 0;
- DWORD method = _osfile(fd) & FAPPEND ? FILE_END : FILE_CURRENT;
+ /* On mode:a, it can write only FILE_END.
+ * On mode:a+, though it can write only FILE_END,
+ * it can read from everywhere.
+ */
+ DWORD method = ((_osfile(fd) & FAPPEND) && iswrite) ? FILE_END : FILE_CURRENT;
DWORD low = SetFilePointer((HANDLE)_osfhnd(fd), 0, &high, method);
#ifndef INVALID_SET_FILE_POINTER
#define INVALID_SET_FILE_POINTER ((DWORD)-1)
@@ -6578,7 +6582,7 @@ rb_w32_read(int fd, void *buf, size_t size)
/* if have cancel_io, use Overlapped I/O */
if (cancel_io) {
- if (setup_overlapped(&ol, fd)) {
+ if (setup_overlapped(&ol, fd, FALSE)) {
rb_acrt_lowio_unlock_fh(fd);
return -1;
}
@@ -6708,7 +6712,7 @@ rb_w32_write(int fd, const void *buf, size_t size)
/* if have cancel_io, use Overlapped I/O */
if (cancel_io) {
- if (setup_overlapped(&ol, fd)) {
+ if (setup_overlapped(&ol, fd, TRUE)) {
rb_acrt_lowio_unlock_fh(fd);
return -1;
}
</code></pre>
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 #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 - 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 - Bug #8711 (Closed): 最近NoMemoryErrorが多い
https://redmine.ruby-lang.org/issues/8711
2013-07-31T16:06:27Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>最近 rubyci で NoMemoryError を出して失敗することが多いので、それを追跡するスレ</p>
<p>= TestFiber#test_many_fibers<br>
<a href="http://u64b.rubyci.org/~chkbuild/ruby-trunk/log/20130730T233301Z.diff.html.gz" class="external">http://u64b.rubyci.org/~chkbuild/ruby-trunk/log/20130730T233301Z.diff.html.gz</a><br>
<a href="http://rbci.lakewood.privs.net/ruby-trunk/log/20130731T001002Z.diff.html.gz" class="external">http://rbci.lakewood.privs.net/ruby-trunk/log/20130731T001002Z.diff.html.gz</a></p>
<p>= FiberError: can't alloc machine stack to fiber<br>
<a href="http://u64.rubyci.org/~chkbuild/ruby-trunk/log/20130729T200302Z.diff.html.gz" class="external">http://u64.rubyci.org/~chkbuild/ruby-trunk/log/20130729T200302Z.diff.html.gz</a></p>
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 #8539 (Closed): Unbundle ext/tk
https://redmine.ruby-lang.org/issues/8539
2013-06-18T00:25:36Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>How about unbundling ext/tk from Ruby repository?</p>
<p>ext/tk is a bundled extension library for GUI programming with tk.<br>
It is introduced in 1999 and long maintained with CRuby itself.</p>
<p>But nowadays its maintenance is not so active.<br>
Moreover ext/tk is not the de facto standard over Ruby GUI though it is bundled for 14 years.<br>
(maybe because tk is not de facto of GUI toolkit)<br>
GUI libraries for Ruby should compete in the wilds.</p>
<p>So I propose unbundling ext/tk.<br>
It should be another repository for example on github and people should install it as gem.</p>
<p>How do you think?</p>
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 - Bug #8408 (Closed): minitest's test may fail randomly
https://redmine.ruby-lang.org/issues/8408
2013-05-15T11:54:58Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>test/minitest/test_minitest_spec.rb may fail as following:<br>
<a href="http://c5664.rubyci.org/~chkbuild/ruby-trunk/log/20130515T013301Z.log.html.gz" class="external">http://c5664.rubyci.org/~chkbuild/ruby-trunk/log/20130515T013301Z.log.html.gz</a></p>
<ol start="9">
<li>
<p>Failure:<br>
TestMeta#test_structure_subclasses [/home/chkbuild/build/20130515T013301Z/ruby/test/minitest/test_minitest_spec.rb:751]:<br>
Expected #<#<a href="Class:0x002abd3bcfd7f8" class="external">Class:0x002abd3bcfd7f8</a>:0x002abd3bf000f0 @<strong>name</strong>=nil, @<strong>io</strong>=nil, @passed=nil> (top-level thingy::inner) to respond to #xyz.</p>
</li>
<li>
<p>Failure:<br>
TestMeta#test_name [/home/chkbuild/build/20130515T013301Z/ruby/test/minitest/test_minitest_spec.rb:668]:<br>
Expected: "ExampleA"<br>
Actual: "top-level thingy::ExampleA"</p>
</li>
<li>
<p>Failure:<br>
TestMeta#test_structure [/home/chkbuild/build/20130515T013301Z/ruby/test/minitest/test_minitest_spec.rb:687]:<br>
--- expected<br>
+++ actual<br>
@@ -1 +1 @@<br>
-"top-level thingy"<br>
+"top-level thingy::top-level thingy"</p>
</li>
<li>
<p>Failure:<br>
TestMeta#test_name2 [/home/chkbuild/build/20130515T013301Z/ruby/test/minitest/test_minitest_spec.rb:680]:<br>
Expected: "ExampleA"<br>
Actual: "top-level thingy::ExampleA"</p>
</li>
</ol>
<p>It seems because of minitest's bug.<br>
minitest's parallelize_me! make tests parallell but its describe method uses single stack.</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>
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 #8203 (Closed): Rinda: recycled object
https://redmine.ruby-lang.org/issues/8203
2013-04-02T11:00:13Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>test-allで以下のメッセージが出ているんですが、これってなんですか?<br>
<a href="http://u32.rubyci.org/~chkbuild/ruby-trunk/log/20130402T010302Z.log.html.gz#test-all" class="external">http://u32.rubyci.org/~chkbuild/ruby-trunk/log/20130402T010302Z.log.html.gz#test-all</a></p>
<p>Rinda::TupleSpaceProxyTest#test_take_bug_8215 = /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:369:in <code>_id2ref': 0xda91ca76 is recycled object (RangeError) from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:369:in </code>to_obj'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:1446:in <code>to_obj' from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:1748:in </code>to_obj'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:1025:in <code>_load' from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:590:in </code>load'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:590:in <code>block in load' from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:586:in </code>synchronize'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:586:in <code>load' from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:638:in </code>recv_reply'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:936:in <code>recv_reply' from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:1222:in </code>send_message'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:1110:in <code>block (2 levels) in method_missing' from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:1197:in </code>open'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:1109:in <code>block in method_missing' from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:1132:in </code>with_friend'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/drb/drb.rb:1108:in <code>method_missing' from /home/chkbuild/build/20130402T010302Z/ruby/lib/rinda/rinda.rb:265:in </code>write'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/test/rinda/test_rinda.rb:506:in <code>block in test_take_bug_8215' from /home/chkbuild/build/20130402T010302Z/ruby/test/rinda/test_rinda.rb:502:in </code>fork'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/test/rinda/test_rinda.rb:502:in <code>test_take_bug_8215' from /home/chkbuild/build/20130402T010302Z/ruby/lib/test/unit.rb:858:in </code>run_test'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/minitest/unit.rb:1301:in <code>run' from /home/chkbuild/build/20130402T010302Z/ruby/lib/test/unit/testcase.rb:17:in </code>run'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/minitest/unit.rb:919:in <code>block in _run_suite' from /home/chkbuild/build/20130402T010302Z/ruby/lib/minitest/unit.rb:912:in </code>map'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/minitest/unit.rb:912:in <code>_run_suite' from /home/chkbuild/build/20130402T010302Z/ruby/lib/test/unit.rb:657:in </code>block in _run_suites'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/test/unit.rb:655:in <code>each' from /home/chkbuild/build/20130402T010302Z/ruby/lib/test/unit.rb:655:in </code>_run_suites'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/minitest/unit.rb:867:in <code>_run_anything' from /home/chkbuild/build/20130402T010302Z/ruby/lib/minitest/unit.rb:1060:in </code>run_tests'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/minitest/unit.rb:1047:in <code>block in _run' from /home/chkbuild/build/20130402T010302Z/ruby/lib/minitest/unit.rb:1046:in </code>each'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/minitest/unit.rb:1046:in <code>_run' from /home/chkbuild/build/20130402T010302Z/ruby/lib/minitest/unit.rb:1035:in </code>run'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/test/unit.rb:21:in <code>run' from /home/chkbuild/build/20130402T010302Z/ruby/lib/test/unit.rb:774:in </code>run'<br>
from /home/chkbuild/build/20130402T010302Z/ruby/lib/test/unit.rb:834:in <code>run' from /home/chkbuild/build/20130402T010302Z/ruby/lib/test/unit.rb:838:in </code>run'<br>
from ./test/runner.rb:17:in `'<br>
1.42 s = .</p>
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>
Ruby master - Feature #6910 (Rejected): Loading syck's broken yaml with psych
https://redmine.ruby-lang.org/issues/6910
2012-08-23T11:04:21Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>You know, syck outputs wrong yaml.<br>
For example, syck works as following:</p>
<p>ruby-1.9.2 > ["\u3042",Time.at(0).to_s].to_yaml<br>
=> "--- \n- "\xE3\x81\x82"\n- 1970-01-01 09:00:00 +09:00\n"</p>
<p>It should be</p>
<p>ruby-1.9.3 > ["\u3042",Time.at(0).to_s].to_yaml<br>
=> "---\n- あ\n- '1970-01-01 09:00:00 +0900'\n"</p>
<p>syck's dump of Unicode string is interpreted as "\u00E3\u0081\u0082".<br>
syck's dump of Time like string is interpreted as Time.<br>
It is hard to migrate old data to new and correct data, so it is useful if psych has a such compatibility option.</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 - Bug #6400 (Closed): dl/callback with fiddle occurs SEGV on NetBSD amd64
https://redmine.ruby-lang.org/issues/6400
2012-05-04T21:33:37Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>On NetBSD amd64, libffi with callback occurs SEGV as following.</p>
<p>kelvena% cat p<br>
require 'dl/callback'<br>
require 'dl/func'<br>
include DL<br>
Called_with = nil<br>
addr = set_callback(TYPE_VOID, 1) do |str|<br>
called_with = dlunwrap(str)<br>
end<br>
func = CFunc.new(addr, TYPE_VOID, 'test')<br>
f = Function.new(func, [TYPE_VOIDP])<br>
arg = 'foo'<br>
f.call(dlwrap(arg))<br>
kelvena% ./ruby p<br>
/home/naruse/local/ruby/lib/ruby/2.0.0/dl/func.rb:55: [BUG] Segmentation fault<br>
ruby 2.0.0dev (2012-04-30 trunk 35500) [x86_64-netbsd6.99.5]</p>
<p>-- Control frame information -----------------------------------------------<br>
c:0005 p:---- s:0022 b:0022 l:000021 d:000021 CFUNC :call<br>
c:0004 p:0059 s:0018 b:0018 l:000017 d:000017 METHOD /home/naruse/local/ruby/lib/ruby/2.0.0/dl/func.<br>
rb:55<br>
c:0003 p:0157 s:0010 b:0010 l:001db8 d:0021a8 EVAL p:11<br>
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH<br>
c:0001 p:0000 s:0002 b:0002 l:001db8 d:001db8 TOP</p>
<p>-- Ruby level backtrace information ----------------------------------------<br>
p:11:in <code><main>' /home/naruse/local/ruby/lib/ruby/2.0.0/dl/func.rb:55:in </code>call'<br>
/home/naruse/local/ruby/lib/ruby/2.0.0/dl/func.rb:55:in `call'</p>
<p>-- Other runtime information -----------------------------------------------</p>
<ul>
<li>
<p>Loaded script: p</p>
</li>
<li>
<p>Loaded features:</p>
<p>0 enumerator.so<br>
1 /home/naruse/local/ruby/lib/ruby/2.0.0/x86_64-netbsd6.99.5/enc/encdb.so<br>
2 /home/naruse/local/ruby/lib/ruby/2.0.0/x86_64-netbsd6.99.5/enc/trans/transdb.so<br>
3 /home/naruse/local/ruby/lib/ruby/2.0.0/rubygems/defaults.rb<br>
4 /home/naruse/local/ruby/lib/ruby/2.0.0/x86_64-netbsd6.99.5/rbconfig.rb<br>
5 /home/naruse/local/ruby/lib/ruby/2.0.0/rubygems/deprecate.rb<br>
6 /home/naruse/local/ruby/lib/ruby/2.0.0/rubygems/exceptions.rb<br>
7 /home/naruse/local/ruby/lib/ruby/2.0.0/rubygems/custom_require.rb<br>
8 /home/naruse/local/ruby/lib/ruby/2.0.0/rubygems.rb<br>
9 /home/naruse/local/ruby/lib/ruby/2.0.0/x86_64-netbsd6.99.5/dl.so<br>
10 /home/naruse/local/ruby/lib/ruby/2.0.0/x86_64-netbsd6.99.5/fiddle.so<br>
11 /home/naruse/local/ruby/lib/ruby/2.0.0/fiddle/function.rb<br>
12 /home/naruse/local/ruby/lib/ruby/2.0.0/fiddle/closure.rb<br>
13 /home/naruse/local/ruby/lib/ruby/2.0.0/fiddle.rb<br>
14 /home/naruse/local/ruby/lib/ruby/2.0.0/dl.rb<br>
15 /home/naruse/local/ruby/lib/ruby/2.0.0/thread.rb<br>
16 /home/naruse/local/ruby/lib/ruby/2.0.0/dl/callback.rb<br>
17 /home/naruse/local/ruby/lib/ruby/2.0.0/dl/stack.rb<br>
18 /home/naruse/local/ruby/lib/ruby/2.0.0/dl/value.rb<br>
19 /home/naruse/local/ruby/lib/ruby/2.0.0/dl/func.rb</p>
</li>
</ul>
<p>[NOTE]<br>
You may have encountered a bug in the Ruby interpreter or extension libraries.<br>
Bug reports are welcome.<br>
For details: <a href="http://www.ruby-lang.org/bugreport.html" class="external">http://www.ruby-lang.org/bugreport.html</a></p>
<p>zsh: abort (core dumped) ./ruby p</p>
Ruby master - Bug #6140 (Rejected): test
https://redmine.ruby-lang.org/issues/6140
2012-03-14T17:28:04Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>Redmineを1.3.2にしたのでテスト</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 - 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 #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>
Ruby master - Feature #5142 (Rejected): Remove ruby-mode.el from ruby's repo
https://redmine.ruby-lang.org/issues/5142
2011-08-02T10:46:33Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>ruby-mode.el は Emacs に添付されるようになりましたが、<br>
今も Ruby のリポジトリ内に misc/ruby-mode.el として存在し続けています。<br>
マスタが Ruby と Emacs の2つあるのも良くないですし、放置されているチケットも多いので、<br>
Ruby のリポジトリからは削除してしまいませんか。</p>
<p>なお、ruby-mode.el 以外の *.el についてはこのチケットの管轄外とします。</p>
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 - 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 - Feature #4529 (Rejected): date_core と long 型
https://redmine.ruby-lang.org/issues/4529
2011-03-26T06:13:43Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
おそらく既にご存じの通り、最近 date_core も含めて ext 中の shorten-64-to-32 を直しています。<br>
それに際して date_core をいじっていて気づいたのですが、ユリウス日や年を long で保持したり int で保持したりしています。</p>
<p>int と long が混在していると、long から int へのキャスト時にオーバーフローが起こりえますし、<br>
そもそも long は</p>
<ul>
<li>環境によってサイズが違う (int も 理屈の上では違うはずだが、CRuby では 32bit しか確認してない)</li>
<li>long は mswin64 でだけポインタとサイズが違うので、Unix な人には気づきづらいバグの温床になる<br>
というような懸念があるので、特に理由が無いのであれば、int にするか、int64_t にするかした方がよいかと思います。<br>
(CRuby は C90 だが、int64_t を configure で定義している)</li>
</ul>
<p>例えば int に統一する場合のパッチは以下の通りです</p>
<p>=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 - Feature #3961 (Rejected): printfと精度指定と負の値と
https://redmine.ruby-lang.org/issues/3961
2010-10-18T18:01:01Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
printf が、フォーマットに精度指定しつつ負の値を与えた時の挙動が、<br>
Perl と必然性無く異なっていて不便です。</p>
<p>% ./ruby -e'printf("%#.8x", -1)'<br>
0x..ffffff</p>
<p>そもそもこの挙動は C 言語由来で、C の場合例えば以下の通りになります。</p>
<p>% cat test.c<br>
#include <stdio.h><br>
int main(void)<br>
{<br>
printf("%#x\n", -1);<br>
return 0;<br>
}<br>
% cc t.c && ./a.out<br>
0xffffffff</p>
<p>また、おそらく直接参考にしたであろう Perl では以下の通りです、<br>
% perl -e'printf("%#x",-1)'<br>
0xffffffffffffffff<br>
% perl -e'printf("%#.30x",-1)'<br>
0x00000000000000ffffffffffffffff<br>
つまり、Perl (の 64bit int 版) では、64bitで補数を取っています。</p>
<p>さて、Ruby の場合多倍長整数が組み込みなため、補数を取ると無限に続いてしまうから、<br>
% ./ruby -e'printf("%#x",-1)'<br>
0x..f<br>
と .. で略すのは理にかなっていると思います。</p>
<p>しかし、現在の Ruby は精度を指定した際にも..がついてしまうので、<br>
Perl のような動きを実現させる事ができません。<br>
% ./ruby -e'printf("%#.8x",-1)'<br>
0x..ffffff<br>
で、この .. っていらないと思うんです。</p>
<p>例えば浮動小数点数の場合には以下のように .. とか付けずにぶった切る訳で、<br>
無限大方向と無限小方向という違いはあれど、<br>
「Perlとかと同じ挙動にできない」というデメリットの方が大きいのではないでしょうか。<br>
% ./ruby -e'printf("%#.8f",10.0/3)'<br>
3.33333333</p>
<p>わたしの場合、CRuby 側の inspect が printf("%x", negative_value) などとしている部分の動作を<br>
RubySpec で Ruby で書く時に頭を抱えてしまいました。</p>
<p>というわけでパッチは例えば以下の通りです。</p>
<p>diff --git a/sprintf.c b/sprintf.c<br>
index 21509ea..0e97955 100644<br>
--- a/sprintf.c<br>
+++ b/sprintf.c<br>
@@ -844,7 +844,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)<br>
}<br>
else {<br>
s = nbuf;</p>
<ul>
<li>
<pre><code> if (v < 0) {
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> if (v < 0 && !(flags & FPREC0)) {
dots = 1;
}
snprintf(fbuf, sizeof(fbuf), "%%l%c", *p == 'X' ? 'x' : *p);
</code></pre>
</li>
</ul>
<p>@@ -892,7 +892,8 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)<br>
tmp1 = tmp = rb_big2str0(val, base, RBIGNUM_SIGN(val));<br>
s = RSTRING_PTR(tmp);<br>
if (*s == '-') {</p>
<ul>
<li>
<pre><code> dots = 1;
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> if (!(flags & FPREC0))
</code></pre>
</li>
<li>
<pre><code> dots = 1;
if (base == 10) {
rb_warning("negative number for %%u specifier");
}
</code></pre>
</li>
</ul>
<p>@@ -925,14 +926,11 @@ rb_str_format(int argc, const VALUE <em>argv, VALUE fmt)<br>
}<br>
}<br>
if (prefix && !prefix[1]) { /</em> octal */</p>
<ul>
<li>
<pre><code> if (dots) {
</code></pre>
</li>
<li>
<pre><code> prefix = 0;
</code></pre>
</li>
<li>
<pre><code> }
</code></pre>
</li>
<li>
<pre><code> else if (len == 1 && *s == '0') {
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> if (len == 1 && *s == '0') {
len = 0;
if (flags & FPREC) prec--;
}
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> else if ((flags & FPREC) && (prec > len)) {
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> else if ((flags & FPREC) && (prec > len) && v >= 0) {
prefix = 0;
}
}
</code></pre>
</li>
</ul>
<p>diff --git a/test/ruby/test_sprintf.rb b/test/ruby/test_sprintf.rb<br>
index 96a1b62..24b6a34 100644<br>
--- a/test/ruby/test_sprintf.rb<br>
+++ b/test/ruby/test_sprintf.rb<br>
@@ -24,12 +24,12 @@ class TestSprintf < Test::Unit::TestCase<br>
assert_equal("0000", sprintf("%.4b", 0))<br>
assert_equal("0001", sprintf("%.4b", 1))<br>
assert_equal("0010", sprintf("%.4b", 2))</p>
<ul>
<li>assert_equal("..11", sprintf("%.4b", -1))</li>
</ul>
<ul>
<li>
<p>assert_equal("1111", sprintf("%.4b", -1))</p>
<p>assert_equal(" 0000", sprintf("%6.4b", 0))<br>
assert_equal(" 0001", sprintf("%6.4b", 1))<br>
assert_equal(" 0010", sprintf("%6.4b", 2))</p>
</li>
</ul>
<ul>
<li>assert_equal(" ..11", sprintf("%6.4b", -1))</li>
</ul>
<ul>
<li>
<p>assert_equal(" 1111", sprintf("%6.4b", -1))</p>
<p>assert_equal(" 0", sprintf("%#4b", 0))<br>
assert_equal(" 0b1", sprintf("%#4b", 1))<br>
@@ -44,12 +44,12 @@ class TestSprintf < Test::Unit::TestCase<br>
assert_equal("0000", sprintf("%#.4b", 0))<br>
assert_equal("0b0001", sprintf("%#.4b", 1))<br>
assert_equal("0b0010", sprintf("%#.4b", 2))</p>
</li>
</ul>
<ul>
<li>assert_equal("0b..11", sprintf("%#.4b", -1))</li>
</ul>
<ul>
<li>
<p>assert_equal("0b1111", sprintf("%#.4b", -1))</p>
<p>assert_equal(" 0000", sprintf("%#6.4b", 0))<br>
assert_equal("0b0001", sprintf("%#6.4b", 1))<br>
assert_equal("0b0010", sprintf("%#6.4b", 2))</p>
</li>
</ul>
<ul>
<li>assert_equal("0b..11", sprintf("%#6.4b", -1))</li>
</ul>
<ul>
<li>
<p>assert_equal("0b1111", sprintf("%#6.4b", -1))</p>
<p>assert_equal("+0", sprintf("%+b", 0))<br>
assert_equal("+1", sprintf("%+b", 1))<br>
@@ -288,6 +288,8 @@ class TestSprintf < Test::Unit::TestCase<br>
b1 = (/../ =~ s1) != nil<br>
b2 = (/../ =~ s2) != nil<br>
assert(b1 == b2, "<a href="https://blade.ruby-lang.org/ruby-dev/33224">[ruby-dev:33224]</a>")</p>
</li>
<li>
<li>
<p>assert_equal("ffffffff", sprintf("%.8x", -1))<br>
end</p>
</li>
</ul>
<pre><code>def test_named
</code></pre>
<p>diff --git a/test/ruby/test_sprintf_comb.rb b/test/ruby/test_sprintf_comb.rb<br>
index 261732b..3105127 100644<br>
--- a/test/ruby/test_sprintf_comb.rb<br>
+++ b/test/ruby/test_sprintf_comb.rb<br>
@@ -190,7 +190,7 @@ class TestSprintfComb < Test::Unit::TestCase<br>
if digits.last != radix-1<br>
digits << (radix-1)<br>
end</p>
<ul>
<li>
<pre><code> sign = '..'
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> sign = '..' unless precision
else
sign = '-'
end
</code></pre>
</li>
</ul>
<p>@@ -222,8 +222,8 @@ class TestSprintfComb < Test::Unit::TestCase<br>
end<br>
end<br>
if type == 'o' && hs</p>
<ul>
<li>
<pre><code> if digits.empty? || digits.last != d
</code></pre>
</li>
<li>
<pre><code> digits << d
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> if digits.empty? || digits.last != 0
</code></pre>
</li>
<li>
<pre><code> prefix = '0'
end
</code></pre>
end<br>
=end</li>
</ul>
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 master - Bug #2724 (Third Party's Issue): fork from other than the main thread causes wrong ...
https://redmine.ruby-lang.org/issues/2724
2010-02-09T03:04:20Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>NetBSD 5.0.[01] において、main thread 以外の pthread から fork すると、<br>
pthread とカーネルスレッド (lwp) との関連が壊れるという現象が確認されています。</p>
<p>後述のパッチがあまりにアレなのでこの問題は Third Party's Issue とし、<br>
Ruby 側では修正を入れない事としますが、情報の共有と記録のために<br>
ここにチケットを切っておきます。</p>
<p>なお、この workaround の作成には @_enamiさんの助けがありました。</p>
<p>追記:<br>
NetBSD 側では kern/42772 として報告、修正されています。<br>
<a href="http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=42772" class="external">http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=42772</a></p>
<a name="Index-thread_pthreadc"></a>
<h1 >Index: thread_pthread.c<a href="#Index-thread_pthreadc" class="wiki-anchor">¶</a></h1>
<p>--- thread_pthread.c (revision 26615)<br>
+++ thread_pthread.c (working copy)<br>
@@ -17,6 +17,93 @@<br>
#include <sys/resource.h><br>
#endif</p>
<p>+#if defined(<strong>NetBSD_Version</strong>) && <strong>NetBSD_Version</strong> >= 500000000<br>
+/* Hack for NetBSD 5.0.x's broken pthread->pt_lid <em>/<br>
+/</em> Copied from /src/lib/libpthread/pthread_int.h <em>/<br>
+#define BROKEN_PTHREAD_T_PT_LID<br>
+#include <lwp.h><br>
+#include <pthread_queue.h><br>
+#include <sys/tree.h><br>
+<br>
+#define PTHREAD_KEYS_MAX 256<br>
+#define PTHREAD__UNPARK_MAX 32<br>
+<br>
+/</em></p>
<ul>
<li>
<ul>
<li>The size of this structure needs to be no larger than struct</li>
</ul>
</li>
<li>
<ul>
<li>__pthread_cleanup_store, defined in pthread.h.</li>
</ul>
</li>
<li>*/<br>
+struct pt_clean_t {</li>
<li>
<pre><code> PTQ_ENTRY(pt_clean_t) ptc_next;
</code></pre>
</li>
<li>
<pre><code> void (*ptc_cleanup)(void *);
</code></pre>
</li>
<li>
<pre><code> void *ptc_arg;
</code></pre>
</li>
</ul>
<p>+};<br>
+<br>
+struct pthread_lock_ops {</p>
<ul>
<li>
<pre><code> void (*plo_init)(__cpu_simple_lock_t *);
</code></pre>
</li>
<li>
<pre><code> int (*plo_try)(__cpu_simple_lock_t *);
</code></pre>
</li>
<li>
<pre><code> void (*plo_unlock)(__cpu_simple_lock_t *);
</code></pre>
</li>
<li>
<pre><code> void (*plo_lock)(__cpu_simple_lock_t *);
</code></pre>
</li>
</ul>
<p>+};<br>
+<br>
+struct __pthread_st {</p>
<ul>
<li>
<pre><code> pthread_t pt_self; /* Must be first. */
</code></pre>
</li>
<li>
<pre><code> unsigned int pt_magic; /* Magic number */
</code></pre>
</li>
<li>
<pre><code> int pt_state; /* running, blocked, etc. */
</code></pre>
</li>
<li>
<pre><code> pthread_mutex_t pt_lock; /* lock on state */
</code></pre>
</li>
<li>
<pre><code> int pt_flags; /* see PT_FLAG_* below */
</code></pre>
</li>
<li>
<pre><code> int pt_cancel; /* Deferred cancellation */
</code></pre>
</li>
<li>
<pre><code> int pt_errno; /* Thread-specific errno. */
</code></pre>
</li>
<li>
<pre><code> stack_t pt_stack; /* Our stack */
</code></pre>
</li>
<li>
<pre><code> void *pt_exitval; /* Read by pthread_join() */
</code></pre>
</li>
<li>
<pre><code> char *pt_name; /* Thread's name, set by the app. */
</code></pre>
</li>
<li>
<pre><code> int pt_willpark; /* About to park */
</code></pre>
</li>
<li>
<pre><code> lwpid_t pt_unpark; /* Unpark this when parking */
</code></pre>
</li>
<li>
<pre><code> struct pthread_lock_ops pt_lockops;/* Cached to avoid PIC overhead */
</code></pre>
</li>
<li>
<pre><code> pthread_mutex_t *pt_droplock; /* Drop this lock if cancelled */
</code></pre>
</li>
<li>
<pre><code> pthread_cond_t pt_joiners; /* Threads waiting to join. */
</code></pre>
</li>
<li>
<li>
<pre><code> /* Threads to defer waking, usually until pthread_mutex_unlock(). */
</code></pre>
</li>
<li>
<pre><code> lwpid_t pt_waiters[PTHREAD__UNPARK_MAX];
</code></pre>
</li>
<li>
<pre><code> size_t pt_nwaiters;
</code></pre>
</li>
<li>
<li>
<pre><code> /* Stack of cancellation cleanup handlers and their arguments */
</code></pre>
</li>
<li>
<pre><code> PTQ_HEAD(, pt_clean_t) pt_cleanup_stack;
</code></pre>
</li>
<li>
<li>
<pre><code> /* LWP ID and entry on the list of all threads. */
</code></pre>
</li>
<li>
<pre><code> lwpid_t pt_lid;
</code></pre>
</li>
<li>
<pre><code> RB_ENTRY(__pthread_st) pt_alltree;
</code></pre>
</li>
<li>
<pre><code> PTQ_ENTRY(__pthread_st) pt_allq;
</code></pre>
</li>
<li>
<pre><code> PTQ_ENTRY(__pthread_st) pt_deadq;
</code></pre>
</li>
<li>
<li>
<pre><code> /*
</code></pre>
</li>
<li>
<pre><code> * General synchronization data. We try to align, as threads
</code></pre>
</li>
<li>
<pre><code> * on other CPUs will access this data frequently.
</code></pre>
</li>
<li>
<pre><code> */
</code></pre>
</li>
<li>
<pre><code> int pt_dummy1 __aligned(128);
</code></pre>
</li>
<li>
<pre><code> struct lwpctl *pt_lwpctl; /* Kernel/user comms area */
</code></pre>
</li>
<li>
<pre><code> volatile int pt_blocking; /* Blocking in userspace */
</code></pre>
</li>
<li>
<pre><code> volatile int pt_rwlocked; /* Handed rwlock successfully */
</code></pre>
</li>
<li>
<pre><code> volatile int pt_signalled; /* Received pthread_cond_signal() */
</code></pre>
</li>
<li>
<pre><code> volatile int pt_mutexwait; /* Waiting to acquire mutex */
</code></pre>
</li>
<li>
<pre><code> void * volatile pt_mutexnext; /* Next thread in chain */
</code></pre>
</li>
<li>
<pre><code> void * volatile pt_sleepobj; /* Object slept on */
</code></pre>
</li>
<li>
<pre><code> PTQ_ENTRY(__pthread_st) pt_sleep;
</code></pre>
</li>
<li>
<pre><code> void (*pt_early)(void *);
</code></pre>
</li>
<li>
<pre><code> int pt_dummy2 __aligned(128);
</code></pre>
</li>
<li>
<li>
<pre><code> /* Thread-specific data. Large so it sits close to the end. */
</code></pre>
</li>
<li>
<pre><code> int pt_havespecific;
</code></pre>
</li>
<li>
<pre><code> void *pt_specific[PTHREAD_KEYS_MAX];
</code></pre>
</li>
<li>
<li>
<pre><code> /*
</code></pre>
</li>
<li>
<pre><code> * Context for thread creation. At the end as it's cached
</code></pre>
</li>
<li>
<pre><code> * and then only ever passed to _lwp_create().
</code></pre>
</li>
<li>
<pre><code> */
</code></pre>
</li>
<li>
<pre><code> ucontext_t pt_uc;
</code></pre>
</li>
</ul>
<p>+};<br>
+#endif /* <strong>NetBSD</strong> */<br>
+<br>
+<br>
static void native_mutex_lock(pthread_mutex_t *lock);<br>
static void native_mutex_unlock(pthread_mutex_t *lock);<br>
static int native_mutex_trylock(pthread_mutex_t *lock);<br>
@@ -833,6 +920,9 @@<br>
native_reset_timer_thread(void)<br>
{<br>
timer_thread_id = 0;<br>
+#ifdef BROKEN_PTHREAD_T_PT_LID</p>
<ul>
<li>((struct __pthread_st *)pthread_self())->pt_lid = _lwp_self();<br>
+#endif<br>
}</li>
</ul>
<p>#ifdef HAVE_SIGALTSTACK</p>
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>
Ruby master - Feature #2586 (Rejected): openssl: Load root certificates on Windows
https://redmine.ruby-lang.org/issues/2586
2010-01-10T15:27:08Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
On Unix, ext/openssl can use the system's root certificates.<br>
But on Windows root certificates are not provided as files.</p>
<p>By this patch, OpenSSL::X509::Store#set_default_paths can load<br>
root certificates bundled with Windows.<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 - Feature #2454 (Rejected): OpenSSL has no maintainer
https://redmine.ruby-lang.org/issues/2454
2009-12-08T00:54:31Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
OpenSSL is famous security library and Ruby has a wrapper for it.<br>
But it has no maintainer now.<br>
We, aren't familiar with this security related library, don't want maintain this.<br>
This situation prevent merging path for OpenSSL 1.0 and other requests.</p>
<p>So anyone can maintain ext/openssl or review patches for ext/openssl?<br>
=end</p>
Ruby master - Feature #2340 (Rejected): Removing YAML/Syck
https://redmine.ruby-lang.org/issues/2340
2009-11-06T17:16:10Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
YAML and Syck is a _why's product and widely used bundled library of Ruby.<br>
But they are not maintained for 2 years and no more by _why.<br>
And they support only YAML 1.0, not 1.1 and 1.2.<br>
So YAML/Syck considered harmful.<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 #2017 (Rejected): String#/(sep)
https://redmine.ruby-lang.org/issues/2017
2009-08-31T02:35:22Z
naruse (Yui NARUSE)
naruse@airemix.jp
<p>=begin<br>
String#/(separator) を String#join(separator) の alias として追加しませんか?</p>
<p>以前から、Array#*(sep) との対称性から String#/(sep) の採用は求められてきました。<br>
しかし、対称性だけでは根拠が弱く、入ることなく今に至っています。</p>
<p>今回は、String#split の出現頻度を調べてみました。<br>
Rubyのソースで調べてみると、<br>
% grep split **/<em>.rb|wc -l<br>
1096<br>
% grep gsub **/</em>.rb|wc -l<br>
617<br>
% grep push **/<em>.rb|wc -l<br>
732<br>
% grep to_i **/</em>.rb|wc -l<br>
1034<br>
% grep to_s **/<em>.rb|wc -l<br>
2414<br>
% grep each **/</em>.rb|wc -l<br>
4752<br>
という結果の通り、each や to_s には負けるものの、to_i に並び、<br>
高順位が予想された gsub をも越える使用頻度を誇っています。</p>
<p>これだけの頻度ならば / を割り当てるに足と思うのですが、いかがでしょうか。<br>
もし何かに String#/ をあてるならば、String#split 以外になる可能性は低いように思います。<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>