Ruby Issue Tracking System: Issueshttps://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112023-08-02T05:08:15ZRuby Issue Tracking System
Redmine Ruby master - Bug #19794 (Assigned): Ruby 3.2.2 fails to build on macOS Sonoma betashttps://bugs.ruby-lang.org/issues/197942023-08-02T05:08:15Zjhaungs (Jim Haungs)
<p>With Big Sur, Apple deprecated putting dylibs in /usr/local/lib. In Sonoma (beta 4), this directory has disappeared completely. However, ruby's configure script depends on its existence. So, virtually every ruby installer (RVM, rbenv, asdf, ruby-build, and even building from source tarball) fails.</p>
<p>When building ruby 3.2.2 from source, the configure step outputs the irritatingly useless "something wrong with LDFLAGS" error message and fails to build.</p>
<p>The solution was to <code>cd /usr/local; sudo mkdir lib</code> to create the missing lib directory under /usr/local.</p>
<p>It would be nice to remove this dependency from the configure script.</p> Ruby master - Feature #19465 (Assigned): [PATCH] reuse open(2) from rb_file_load_ok on POSIX-like...https://bugs.ruby-lang.org/issues/194652023-02-25T01:48:35Znormalperson (Eric Wong)normalperson@yhbt.net
<pre><code>When loading Ruby source files, we can save the result of
successful opens as open(2)/openat(2) are a fairly expensive
syscalls. This also avoids a time-of-check-to-time-of-use
(TOCTTOU) problem.
This reduces open(2) syscalls during `require'; but should be
most apparent when users have a small $LOAD_PATH. Users with
large $LOAD_PATH will benefit less since there'll be more
open(2) failures due to ENOENT.
With `strace -c -e openat ruby -e exit' under Linux, this
results in a ~14% reduction of openat(2) syscalls
(glibc uses openat(2) to implement open(2)).
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
0.00 0.000000 0 296 110 openat
0.00 0.000000 0 254 110 openat
Additionally, the introduction of `struct ruby_file_load_state'
may make future optimizations more apparent.
This change cannot benefit binary (.so) loading since the
dlopen(3) API requires a filename and I'm not aware of an
alternative that takes a pre-existing FD. In typical
situations, Ruby source files outnumber the mount of .so
files.
I've only tested this lightly on small apps since I don't have
large codebases to test on. However, I think organizing various
on-stack variables into `struct ruby_file_load_state' can be
beneficial if we end up using io-uring on Linux.
</code></pre> Ruby master - Feature #19193 (Assigned): drop DOS TEXT mode supporthttps://bugs.ruby-lang.org/issues/191932022-12-09T16:38:20ZYO4 (Yoshinao Muramatsu)
<p>On Windows platform, <code>File.open(path, "r")</code> returns an object different from "rt" and "rb". I call that DOS TEXT mode here.</p>
<p>DOS TEXT mode does</p>
<ul>
<li>crlf conversion</li>
<li>0x1a treated EOF charactor on read</li>
</ul>
<p>and others (see Bug <a class="issue tracker-1 status-1 priority-4 priority-default" title="Bug: IO has third data mode, document is incomplete. (Open)" href="https://bugs.ruby-lang.org/issues/19192">#19192</a>).<br>
But DOS TEXT mode is almost unnecessary today and it seems to introduce lot of code complexities.</p>
<p>Now there is less need for dos text mode</p>
<ul>
<li>Microsoft's most apps works without CRLF newline.</li>
<li>Creating a crlf text file today should be explicit. (but that is default mode on windows now)</li>
<li>Interpreting EOF charactor can cause trouble.</li>
</ul>
<p>I think it's time to consider dropping DOS TEXT mode.<br>
What challenges are there and what preparation is needed?</p> Ruby master - Bug #18677 (Assigned): BigDecimal#power (**) returns FloatDomainError when passing ...https://bugs.ruby-lang.org/issues/186772022-04-04T09:27:59Zdorianmariefr (Dorian Marié)
<p>Example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">></span> <span class="no">BigDecimal</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="o">**</span> <span class="no">BigDecimal</span><span class="p">(</span><span class="s2">"Infinity"</span><span class="p">)</span>
<span class="no">FloatDomainError</span><span class="p">:</span> <span class="no">Computation</span> <span class="n">results</span> <span class="k">in</span> <span class="s1">'Infinity'</span>
</code></pre>
<p>Maybe:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s2">"bigdecimal/util"</span>
<span class="k">class</span> <span class="nc">BigDecimal</span> <span class="o"><</span> <span class="no">Numeric</span>
<span class="k">def</span> <span class="nf">**</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">if</span> <span class="n">other</span><span class="p">.</span><span class="nf">infinite?</span> <span class="o">==</span> <span class="mi">1</span>
<span class="k">if</span> <span class="nb">self</span> <span class="o">></span> <span class="mi">1</span>
<span class="no">BigDecimal</span><span class="o">::</span><span class="no">INFINITY</span>
<span class="k">elsif</span> <span class="nb">self</span> <span class="o">==</span> <span class="mi">1</span>
<span class="nb">self</span>
<span class="k">elsif</span> <span class="nb">self</span> <span class="o">>=</span> <span class="mi">0</span>
<span class="no">BigDecimal</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="k">else</span>
<span class="n">power</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">else</span>
<span class="n">power</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">puts_and_eval</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="nb">puts</span> <span class="n">string</span>
<span class="nb">p</span> <span class="nb">eval</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">puts_and_eval</span> <span class="s2">"10 ** BigDecimal::INFINITY"</span>
<span class="n">puts_and_eval</span> <span class="s2">"1 ** BigDecimal::INFINITY"</span>
<span class="n">puts_and_eval</span> <span class="s2">"0.1 ** BigDecimal::INFINITY"</span>
<span class="n">puts_and_eval</span> <span class="s2">"0 ** BigDecimal::INFINITY"</span>
<span class="n">puts_and_eval</span> <span class="s2">"-1 ** BigDecimal::INFINITY"</span>
</code></pre>
<p>Seems like ruby is doing very different things from math though</p> Ruby master - Misc #18371 (Assigned): Release branches (release information in general)https://bugs.ruby-lang.org/issues/183712021-11-30T22:52:11Ztenderlovemaking (Aaron Patterson)tenderlove@ruby-lang.org
<p>Hi,</p>
<p>I was trying to learn about Ruby's release process. I noticed that we don't create a release branch until the final version is shipped. Is there a reason we don't create the release branch when the first preview is shipped? The reason I'm asking is because I'm worried about merging things to master after the first preview. Do we have any documentation on the release process? (I was searching and couldn't find much info, but maybe I didn't search correctly)</p>
<p>Thanks!</p> Ruby master - Misc #17662 (Assigned): The heredoc pattern used in tests does not syntax highlight...https://bugs.ruby-lang.org/issues/176622021-02-27T16:22:19ZEregon (Benoit Daloze)
<p>This heredoc pattern</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="n">assert_ruby_status</span><span class="p">([],</span> <span class="s2">"</span><span class="si">#{</span><span class="o"><<-</span><span class="s2">"begin;"</span><span class="si">}</span><span class="se">\n</span><span class="si">#{</span><span class="o"><<-</span><span class="s1">'end;'</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span> <span class="n">bug</span><span class="p">)</span>
<span class="k">begin</span><span class="p">;</span>
<span class="nb">exit</span><span class="p">(</span><span class="s2">"1"</span> <span class="o">==</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">start</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="o">&</span><span class="ss">:to_s</span><span class="p">).</span><span class="nf">value</span><span class="p">)</span>
<span class="k">end</span><span class="p">;</span>
</code></pre>
<p>completely breaks syntax highlighting in at least:</p>
<ul>
<li>GitHub: <a href="https://github.com/ruby/ruby/blob/36dde35e029c7a6607e6c674062ce6fc7a51c0bd/test/ruby/test_string.rb#L697" class="external">there</a> <a href="https://github.com/ruby/ruby/blob/36dde35e029c7a6607e6c674062ce6fc7a51c0bd/test/ruby/test_process.rb#L1545" class="external">are</a> <a href="https://github.com/ruby/ruby/blob/565aeb81e0886c835888a425e5d05ed99fb03238/test/ruby/test_thread.rb#L201" class="external">many</a> <a href="https://github.com/ruby/ruby/blob/36dde35e029c7a6607e6c674062ce6fc7a51c0bd/test/ruby/test_require.rb#L21" class="external">examples</a>
</li>
<li>Atom</li>
<li>RubyMine (and IntelliJ)</li>
<li>Likely many more editors based on TextMate grammars</li>
</ul>
<p>Could another pattern be used in tests inside the ruby/ruby repository (at least for <code>test/ruby</code>)?</p>
<p>Due to this issue, it is very annoying and inconvenient to look at/read/investigate many tests.</p>
<p>I think this pattern is also very complicated to understand (and using <code>;</code> is quite weird for this).<br>
I suggest to replace it with this obvious and simple pattern many people use:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="n">assert_ruby_status</span><span class="p">([],</span> <span class="o"><<~</span><span class="no">'RUBY'</span><span class="p">,</span> <span class="n">bug</span><span class="p">)</span><span class="sh">
exit("1" == Thread.start(1, &:to_s).value)
</span><span class="no"> RUBY</span>
</code></pre>
<p>This syntax highlights correctly in most (all?) editors, and as an added bonus the code inside the heredoc is also highlighted in some editors (due to the label being <code>RUBY</code>).</p> Ruby master - Feature #17638 (Assigned): Support backtracing with the libbacktrace libraryhttps://bugs.ruby-lang.org/issues/176382021-02-17T13:03:12Zxtkoba (Tee KOBAYASHI)
<p>It seems that Ruby's current <code>addr2line.c</code> has trouble with the DWARF 5 debugging format (Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: DWARF5 support? (Closed)" href="https://bugs.ruby-lang.org/issues/17585">#17585</a>).</p>
<p>I propose that there be an option to use the libbacktrace library instead of <code>addr2line.c</code>.</p>
<p>A patch is attached for that. When using libbacktrace, the C level backtrace information looks as follows:</p>
<pre><code>-- C level backtrace information -------------------------------------------
0x7f0cc2b3b372 rb_vm_bugreport
/var/tmp/ruby.build/ruby-devel-x86_64/vm_dump.c:1047
0x7f0cc291e188 rb_bug_for_fatal_signal
/var/tmp/ruby.build/ruby-devel-x86_64/error.c:801
0x7f0cc2a8a137 sigsegv
/var/tmp/ruby.build/ruby-devel-x86_64/signal.c:960
0x7f0cc281a9bf ???
???:0
0x7f0cc247ddf7 ???
???:0
0x7f0cc2a8990d rb_f_kill
/var/tmp/ruby.build/ruby-devel-x86_64/signal.c:481
0x7f0cc2a2e684 proc_rb_f_kill
/var/tmp/ruby.build/ruby-devel-x86_64/process.c:8604
0x7f0cc2b0f2a4 ractor_safe_call_cfunc_m1
/var/tmp/ruby.build/ruby-devel-x86_64/vm_insnhelper.c:2734
0x7f0cc2b0fecb vm_call_cfunc_with_frame
/var/tmp/ruby.build/ruby-devel-x86_64/vm_insnhelper.c:2924
0x7f0cc2b10088 vm_call_cfunc
/var/tmp/ruby.build/ruby-devel-x86_64/vm_insnhelper.c:2945
0x7f0cc2b11b3b vm_call_method_each_type
/var/tmp/ruby.build/ruby-devel-x86_64/vm_insnhelper.c:3414
0x7f0cc2b11fde vm_call_method
/var/tmp/ruby.build/ruby-devel-x86_64/vm_insnhelper.c:3507
0x7f0cc2b121ca vm_call_general
/var/tmp/ruby.build/ruby-devel-x86_64/vm_insnhelper.c:3550
0x7f0cc2b144e7 vm_sendish
/var/tmp/ruby.build/ruby-devel-x86_64/vm_insnhelper.c:4525
0x7f0cc2b1b196 vm_exec_core
/var/tmp/ruby.build/ruby-devel-x86_64/insns.def:789
0x7f0cc2b308f5 rb_vm_exec
/var/tmp/ruby.build/ruby-devel-x86_64/vm.c:2162
0x7f0cc2b316e8 rb_iseq_eval_main
/var/tmp/ruby.build/ruby-devel-x86_64/vm.c:2419
0x7f0cc292778d rb_ec_exec_node
/var/tmp/ruby.build/ruby-devel-x86_64/eval.c:317
0x7f0cc29278d3 ruby_run_node
/var/tmp/ruby.build/ruby-devel-x86_64/eval.c:375
0x55ad53234234 main
./main.c:47
0x7f0cc2468e59 ???
???:0
0x55ad532340f9 ???
???:0
0xffffffffffffffff ???
???:0
</code></pre>
<p>The source code of libbacktrace is available from: <a href="https://github.com/ianlancetaylor/libbacktrace" class="external">https://github.com/ianlancetaylor/libbacktrace</a></p> Ruby master - Bug #17578 (Assigned): mkmf experimental C++ Supporthttps://bugs.ruby-lang.org/issues/175782021-01-25T06:26:31Zcfis (Charlie Savage)
<p>I've been working on the Rice gem (<a href="https://github.com/jasonroelofs/rice" class="external">https://github.com/jasonroelofs/rice</a>) that wraps C++ code for use in Ruby.</p>
<p>I noticed that some c++ support was added to mkmf for Ruby 2.7. However, if I try to use it find a header it fails to work. For example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">find_header</span><span class="p">(</span><span class="s1">'rice.hpp'</span><span class="p">)</span>
</code></pre>
<p>The reason is the conftest uses gcc -E instead of g++ -E. To fix that requires overlading the cpp_command to support C++.</p>
<p>This the fix I have put in that works:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">MakeMakefile</span><span class="p">[</span><span class="s1">'C++'</span><span class="p">].</span><span class="nf">module_eval</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">cpp_command</span><span class="p">(</span><span class="n">outfile</span><span class="p">,</span> <span class="n">opt</span><span class="o">=</span><span class="s2">""</span><span class="p">)</span>
<span class="n">conf</span> <span class="o">=</span> <span class="n">cc_config</span><span class="p">(</span><span class="n">opt</span><span class="p">)</span>
<span class="k">if</span> <span class="vg">$universal</span> <span class="ow">and</span> <span class="p">(</span><span class="n">arch_flag</span> <span class="o">=</span> <span class="n">conf</span><span class="p">[</span><span class="s1">'ARCH_FLAG'</span><span class="p">])</span> <span class="ow">and</span> <span class="o">!</span><span class="n">arch_flag</span><span class="p">.</span><span class="nf">empty?</span>
<span class="n">conf</span><span class="p">[</span><span class="s1">'ARCH_FLAG'</span><span class="p">]</span> <span class="o">=</span> <span class="n">arch_flag</span><span class="p">.</span><span class="nf">gsub</span><span class="p">(</span><span class="sr">/(?:\G|\s)-arch\s+\S+/</span><span class="p">,</span> <span class="s1">''</span><span class="p">)</span>
<span class="k">end</span>
<span class="no">RbConfig</span><span class="o">::</span><span class="n">expand</span><span class="p">(</span><span class="s2">"$(CXX) -E </span><span class="si">#$INCFLAGS</span><span class="s2"> </span><span class="si">#$CPPFLAGS</span><span class="s2"> </span><span class="si">#$CFLAGS</span><span class="s2"> </span><span class="si">#{</span><span class="n">opt</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="no">CONFTEST_CXX</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">outfile</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span>
<span class="n">conf</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>The two changes over the default method are:</p>
<p>$(CC) -> $(CXX) -E<br>
#{CONFTEST_c} -> #{CONFTEST_cxx}</p>
<p>Could this change be merged in? I can provide a patch file if you would like.</p>
<p>Last, it wasn't obvious to me how to activate the C++ support in mkfm. I ended up doing this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="kp">include</span> <span class="no">MakeMakefile</span><span class="p">[</span><span class="s1">'C++'</span><span class="p">]</span>
</code></pre>
<p>Is that correct?</p> Ruby master - Misc #17376 (Assigned): Reduce number of GitHub Actionshttps://bugs.ruby-lang.org/issues/173762020-12-08T09:45:17Znaruse (Yui NARUSE)naruse@airemix.jp
<p>At this time we have 127 checks for GitHub commits, but unfortunately GitHub UI only shows 100 checks.<br>
It sometimes makes we don't see a failed check.<br>
Could you reduce number of GitHub actions at least less than 100?</p> Ruby master - Feature #17339 (Assigned): Semantic grouping with BigDecimal#to_shttps://bugs.ruby-lang.org/issues/173392020-11-21T07:05:31Zchumaltd (Takahiro Chuma)
<a name="Abstract"></a>
<h1 >Abstract<a href="#Abstract" class="wiki-anchor">¶</a></h1>
<p>Thousands, millions, ... should be expressible with <code>BigDecimal#to_s</code>.</p>
<a name="Background"></a>
<h1 >Background<a href="#Background" class="wiki-anchor">¶</a></h1>
<p><code>BigDecimal('1234567').to_s('3F')</code> returns "123 456 7.0".</p>
<a name="Proposal"></a>
<h1 >Proposal<a href="#Proposal" class="wiki-anchor">¶</a></h1>
<ul>
<li>Have an option with which <code>BigDecimal('1234567').to_s('3F')</code> returns "<em>1 234 567</em>.0".</li>
<li>With decimal, <code>BigDecimal('1234567.8901234').to_s('3F')</code> should return "1 234 567.890 123 4".</li>
<li>Default behavior should be the above in long term.</li>
<li>And/Or, it would be nice to have a pretty method name. I think #to_s('3F') has universal use cases like money calculation.</li>
</ul>
<a name="Discussion"></a>
<h1 >Discussion<a href="#Discussion" class="wiki-anchor">¶</a></h1>
<ul>
<li>International System of Units aka SI defines 3-digit-grouping on long numeric sequence.<br>
<a href="https://www1.bipm.org/jsp/en/ViewCGPMResolution.jsp?CGPM=22&RES=10" class="external">https://www1.bipm.org/jsp/en/ViewCGPMResolution.jsp?CGPM=22&RES=10</a>
</li>
<li>Original discussion in 1948 shows some example of 3-digit-grouping.<br>
<a href="https://www1.bipm.org/utils/common/pdf/CGPM/CGPM9.pdf#page=117" class="external">https://www1.bipm.org/utils/common/pdf/CGPM/CGPM9.pdf#page=117</a>
</li>
</ul>
<a name="Summary"></a>
<h1 >Summary<a href="#Summary" class="wiki-anchor">¶</a></h1>
<p>We want to have a natural format.</p> Ruby master - Feature #17291 (Assigned): Optimize __send__ callhttps://bugs.ruby-lang.org/issues/172912020-10-29T03:05:45Zmrkn (Kenta Murata)muraken@gmail.com
<p>I made a patch to optimize a <code>__send__</code> call. This optimization replaces a <code>__send__</code> method call with a call of the method whose name is the first argument of <code>__send__</code> method. The patch is available in <a href="https://github.com/ruby/ruby/pull/3720" class="external">this pull-request</a>.</p>
<p>By this change, the redefined <code>__send__</code> method is no longer called when it is called by a symbol method name. I guess it is no problem because the following warning message is displayed for a long time.</p>
<pre><code>$ ruby -e 'def __send__; end'
-e:1: warning: redefining `__send__' may cause serious problems
</code></pre>
<p>This proposal introduces two new instructions: <code>sendsym</code> and <code>opt_sendsym_without_block</code>. These instructions handle the cases that the first argument of <code>__send__</code> method is not a symbol literal. I think I can combine these two instructions into one if prefered.</p>
<p>This proposal includes the change proposed in <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Optimize __send__ call with a literal method name (Open)" href="https://bugs.ruby-lang.org/issues/17288">#17288</a>. I'll mark it as a duplicate of this proposal.</p>
<p>I don't handle <code>send</code> method in this proposal. The reason is that we need to examine the redefinition of <code>send</code> method in the instruction execution time. I want to discuss only <code>__send__</code> method in this ticket.</p>
<p>The benchmark result is below:</p>
<pre><code># Iteration per second (i/s)
| |compare-ruby|built-ruby|
|:----------------|-----------:|---------:|
|vm_send_sym | 18.001M| 112.208M|
| | -| 6.23x|
|vm_send_var | 17.779M| 30.922M|
| | -| 1.74x|
|vm_send_var_alt | 3.817M| 6.817M|
| | -| 1.79x|
</code></pre> Ruby master - Feature #17111 (Assigned): Improve performance of Net::HTTPHeader#set_form by 40%https://bugs.ruby-lang.org/issues/171112020-08-10T04:09:30Ztonytonyjan (Weihang Jian)tonytonyjan@gmail.com
<a name="diff"></a>
<h2 >diff<a href="#diff" class="wiki-anchor">¶</a></h2>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/lib/net/http/header.rb b/lib/net/http/header.rb
index a8901e7..3f1a008 100644
</span><span class="gd">--- a/lib/net/http/header.rb
</span><span class="gi">+++ b/lib/net/http/header.rb
</span><span class="p">@@ -475,9 +475,8 @@</span> def set_form(params, enctype='application/x-www-form-urlencoded', formopt={})
@body = nil
@body_stream = nil
@form_option = formopt
<span class="gd">- case enctype
- when /\Aapplication\/x-www-form-urlencoded\z/i,
- /\Amultipart\/form-data\z/i
</span><span class="gi">+ case enctype.downcase
+ when 'application/x-www-form-urlencoded', 'multipart/form-data'
</span> self.content_type = enctype
else
raise ArgumentError, "invalid enctype: #{enctype}"
</code></pre>
<a name="benchmark"></a>
<h2 >benchmark<a href="#benchmark" class="wiki-anchor">¶</a></h2>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'benchmark'</span>
<span class="nb">require</span> <span class="s1">'net/http'</span>
<span class="k">module</span> <span class="nn">Net::HTTPHeader</span>
<span class="k">def</span> <span class="nf">set_form2</span><span class="p">(</span><span class="n">params</span><span class="p">,</span> <span class="n">enctype</span> <span class="o">=</span> <span class="s1">'application/x-www-form-urlencoded'</span><span class="p">,</span> <span class="n">formopt</span> <span class="o">=</span> <span class="p">{})</span>
<span class="vi">@body_data</span> <span class="o">=</span> <span class="n">params</span>
<span class="vi">@body</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="vi">@body_stream</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="vi">@form_option</span> <span class="o">=</span> <span class="n">formopt</span>
<span class="k">case</span> <span class="n">enctype</span><span class="p">.</span><span class="nf">downcase</span>
<span class="k">when</span> <span class="s1">'application/x-www-form-urlencoded'</span><span class="p">,</span> <span class="s1">'multipart/form-data'</span>
<span class="nb">self</span><span class="p">.</span><span class="nf">content_type</span> <span class="o">=</span> <span class="n">enctype</span>
<span class="k">else</span>
<span class="k">raise</span> <span class="no">ArgumentError</span><span class="p">,</span> <span class="s2">"invalid enctype: </span><span class="si">#{</span><span class="n">enctype</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">n</span> <span class="o">=</span> <span class="mi">500_000</span>
<span class="n">request</span> <span class="o">=</span> <span class="no">Net</span><span class="o">::</span><span class="no">HTTP</span><span class="o">::</span><span class="no">Post</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)</span>
<span class="no">Benchmark</span><span class="p">.</span><span class="nf">bm</span> <span class="k">do</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span>
<span class="no">GC</span><span class="p">.</span><span class="nf">disable</span>
<span class="n">x</span><span class="p">.</span><span class="nf">report</span> <span class="p">{</span> <span class="n">n</span><span class="p">.</span><span class="nf">times</span> <span class="p">{</span> <span class="n">request</span><span class="p">.</span><span class="nf">set_form</span> <span class="p">[]</span> <span class="p">}</span> <span class="p">}</span>
<span class="n">x</span><span class="p">.</span><span class="nf">report</span> <span class="p">{</span> <span class="n">n</span><span class="p">.</span><span class="nf">times</span> <span class="p">{</span> <span class="n">request</span><span class="p">.</span><span class="nf">set_form2</span> <span class="p">[]</span> <span class="p">}</span> <span class="p">}</span>
<span class="k">end</span>
</code></pre>
<pre><code> user system total real
0.777054 0.101768 0.878822 ( 0.880472)
0.539860 0.088957 0.628817 ( 0.630178)
</code></pre>
<p>I don't see any test for <code>#set_form</code> in <code>test/net/http/test_httpheader.rb</code>, let me know if I need to add more tests, thanks!</p> Ruby master - Misc #16805 (Assigned): Coroutine's license is unclearhttps://bugs.ruby-lang.org/issues/168052020-04-21T10:23:49Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<p>Files under <code>coroutine/</code> start like this:</p>
<pre><code class="C syntaxhl" data-language="C"><span class="o">/*</span>
<span class="o">*</span> <span class="n">This</span> <span class="n">file</span> <span class="n">is</span> <span class="n">part</span> <span class="n">of</span> <span class="n">the</span> <span class="s">"Coroutine"</span> <span class="n">project</span> <span class="n">and</span> <span class="n">released</span> <span class="n">under</span> <span class="n">the</span> <span class="n">MIT</span> <span class="n">License</span><span class="p">.</span>
<span class="o">*</span>
</code></pre>
<p>The problem is, there is no definition of "the MIT License" throughout the entire project.</p>
<p><a class="user active user-mention" href="https://bugs.ruby-lang.org/users/3344">@ioquatix (Samuel Williams)</a> can you add your terms somewhere inside of LEGAL? There are several other materials also under the MIT license. You can follow how they are listed up.</p> Ruby master - Misc #16747 (Assigned): Repository reorganization requesthttps://bugs.ruby-lang.org/issues/167472020-04-01T06:58:09Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<p>Back in 0.49, there were only 60 files and 3 directories at the root of this project. This was already at some level, but OK-ish. Now, as we are reaching 3.0, we currently have 167 files and 26 directories. The project has grown up. I believe we need some housekeeping.</p>
<p>I would like to introduce directories and move things around, like <a href="https://github.com/jemalloc/jemalloc/" class="external">what they do for jemalloc</a>.</p>
<ul>
<li>Create directory named <code>src</code> and move sources there.</li>
</ul>
<p>There is no need to cargo-cult them so suggestions are welcome.</p> Ruby master - Bug #16497 (Assigned): StringIO#internal_encoding is broken (more severely in 2.7)https://bugs.ruby-lang.org/issues/164972020-01-10T11:18:31Zzverok (Victor Shepelev)zverok.offline@gmail.com
<p>To the best of my understanding from <a href="https://docs.ruby-lang.org/en/master/Encoding.html" class="external">Encoding</a> docs, the following is true:</p>
<ul>
<li>external encoding (explicitly specified or taken from <code>Encoding.default_external</code>) specifies how the IO understands input and stores it internally</li>
<li>internal encoding (explicitly specified or taken from <code>Encoding.default_internal</code>) specifies how the IO converts what it reads.</li>
</ul>
<p>Demonstration with regular files:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># prepare data</span>
<span class="no">File</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="s1">'test.txt'</span><span class="p">,</span> <span class="s1">'Україна'</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s1">'KOI8-U'</span><span class="p">),</span> <span class="ss">encoding: </span><span class="s1">'KOI8-U'</span><span class="p">)</span> <span class="c1">#=> 7</span>
<span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">io</span><span class="p">)</span>
<span class="n">str</span> <span class="o">=</span> <span class="n">io</span><span class="p">.</span><span class="nf">read</span>
<span class="p">[</span><span class="n">io</span><span class="p">.</span><span class="nf">external_encoding</span><span class="p">,</span> <span class="n">io</span><span class="p">.</span><span class="nf">internal_encoding</span><span class="p">,</span> <span class="n">str</span><span class="p">,</span> <span class="n">str</span><span class="p">.</span><span class="nf">encoding</span><span class="p">]</span>
<span class="k">end</span>
<span class="c1"># read it:</span>
<span class="nb">test</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s1">'test.txt'</span><span class="p">,</span> <span class="s1">'r:KOI8-U'</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:KOI8-U>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:KOI8-U>]</span>
<span class="c1"># We can specify internal encoding when opening the file:</span>
<span class="nb">test</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s1">'test.txt'</span><span class="p">,</span> <span class="s1">'r:KOI8-U:UTF-8'</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:KOI8-U>, #<Encoding:UTF-8>, "Україна", #<Encoding:UTF-8>]</span>
<span class="c1"># ...or when it is already opened</span>
<span class="nb">test</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s1">'test.txt'</span><span class="p">).</span><span class="nf">tap</span> <span class="p">{</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="p">.</span><span class="nf">set_encoding</span><span class="p">(</span><span class="s1">'KOI8-U'</span><span class="p">,</span> <span class="s1">'UTF-8'</span><span class="p">)</span> <span class="p">})</span>
<span class="c1"># => [#<Encoding:KOI8-U>, #<Encoding:UTF-8>, "Україна", #<Encoding:UTF-8>]</span>
<span class="c1"># ...or with Encoding.default_internal</span>
<span class="no">Encoding</span><span class="p">.</span><span class="nf">default_internal</span> <span class="o">=</span> <span class="s1">'UTF-8'</span>
<span class="nb">test</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s1">'test.txt'</span><span class="p">,</span> <span class="s1">'r:KOI8-U'</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:KOI8-U>, #<Encoding:UTF-8>, "Україна", #<Encoding:UTF-8>]</span>
</code></pre>
<p>But with StringIO, <strong>internal encoding can't be set</strong> in Ruby <strong>2.6</strong>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'stringio'</span>
<span class="no">Encoding</span><span class="p">.</span><span class="nf">default_internal</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="n">str</span> <span class="o">=</span> <span class="s1">'Україна'</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s1">'KOI8-U'</span><span class="p">)</span>
<span class="c1"># Simplest form:</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:KOI8-U>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:KOI8-U>]</span>
<span class="c1"># Try to set via mode</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">,</span> <span class="s1">'r:KOI8-U:UTF-8'</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:KOI8-U>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:KOI8-U>]</span>
<span class="c1"># Try to set via set_encoding:</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">,</span> <span class="s1">'r:KOI8-U:UTF-8'</span><span class="p">).</span><span class="nf">tap</span> <span class="p">{</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="p">.</span><span class="nf">set_encoding</span><span class="p">(</span><span class="s1">'KOI8-U'</span><span class="p">,</span> <span class="s1">'UTF-8'</span><span class="p">)</span> <span class="p">})</span>
<span class="c1"># => [#<Encoding:KOI8-U>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:KOI8-U>]</span>
<span class="c1"># Try to set via Enoding.default_internal:</span>
<span class="no">Encoding</span><span class="p">.</span><span class="nf">default_internal</span> <span class="o">=</span> <span class="s1">'UTF-8'</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:KOI8-U>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:KOI8-U>]</span>
</code></pre>
<p>So, in 2.6, any attempt to do something with StringIO's internal encoding are <strong>just ignored</strong>.</p>
<p>In <strong>2.7</strong>, though, matters became much worse:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'stringio'</span>
<span class="no">Encoding</span><span class="p">.</span><span class="nf">default_internal</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="n">str</span> <span class="o">=</span> <span class="s1">'Україна'</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s1">'KOI8-U'</span><span class="p">)</span>
<span class="c1"># Behaves same as 2.6</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:KOI8-U>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:KOI8-U>]</span>
<span class="c1"># Try to set via mode: WEIRD behavior starts</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">,</span> <span class="s1">'r:KOI8-U:UTF-8'</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:UTF-8>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:UTF-8>]</span>
<span class="c1"># Try to set via set_encoding: still just ignored</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">,</span> <span class="s1">'r:KOI8-U:UTF-8'</span><span class="p">).</span><span class="nf">tap</span> <span class="p">{</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="p">.</span><span class="nf">set_encoding</span><span class="p">(</span><span class="s1">'KOI8-U'</span><span class="p">,</span> <span class="s1">'UTF-8'</span><span class="p">)</span> <span class="p">})</span>
<span class="c1"># => [#<Encoding:KOI8-U>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:KOI8-U>]</span>
<span class="c1"># Try to set via Enoding.default_internal: WEIRD behavior again</span>
<span class="no">Encoding</span><span class="p">.</span><span class="nf">default_internal</span> <span class="o">=</span> <span class="s1">'UTF-8'</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:UTF-8>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:UTF-8>]</span>
</code></pre>
<p>So, <strong>2.7</strong> not just ignores attempts to set <strong>internal</strong> encoding, but erroneously sets it to <strong>external</strong> one, so strings are not recoded, but their encoding is forced to change.</p>
<p>I believe it is severe bug (more severe than 2.6's "just ignoring").</p>
<p><a href="https://www.reddit.com/r/ruby/comments/emd6q4/is_this_a_stringio_bug_in_ruby_270/" class="external">This Reddit thread</a> shows how it breaks existing code:</p>
<ul>
<li>the author uses <code>StringIO</code> to work with <code>ASCII-8BIT</code> strings;</li>
<li>the code is performed in Rails environment (which sets <code>internal_encoding</code> to <code>UTF-8</code> by default);</li>
<li>under <strong>2.7</strong>, <code>StringIO#read</code> returns <code>ASCII-8BIT</code> content in Strings saying their encoding is <code>UTF-8</code>.</li>
</ul> Ruby master - Feature #16461 (Assigned): Proc#usinghttps://bugs.ruby-lang.org/issues/164612019-12-28T03:32:34Zshugo (Shugo Maeda)
<a name="Overview"></a>
<h2 >Overview<a href="#Overview" class="wiki-anchor">¶</a></h2>
<p>I propose Proc#using to support block-level refinements.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">IntegerDivExt</span>
<span class="n">refine</span> <span class="no">Integer</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">/</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="n">quo</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">instance_eval_with_integer_div_ext</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="n">block</span><span class="p">.</span><span class="nf">using</span><span class="p">(</span><span class="no">IntegerDivExt</span><span class="p">)</span> <span class="c1"># using IntegerDivExt in the block represented by the Proc object</span>
<span class="n">obj</span><span class="p">.</span><span class="nf">instance_eval</span><span class="p">(</span><span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="k">end</span>
<span class="c1"># necessary where blocks are defined (not where Proc#using is called)</span>
<span class="n">using</span> <span class="no">Proc</span><span class="o">::</span><span class="no">Refinements</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> 0</span>
<span class="n">instance_eval_with_integer_div_ext</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">do</span>
<span class="nb">p</span> <span class="nb">self</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> (1/2)</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> 0</span>
</code></pre>
<a name="PoC-implementation"></a>
<h2 >PoC implementation<a href="#PoC-implementation" class="wiki-anchor">¶</a></h2>
<p>For CRuby: <a href="https://github.com/shugo/ruby/pull/2" class="external">https://github.com/shugo/ruby/pull/2</a><br>
For JRuby: <a href="https://github.com/shugo/jruby/pull/1" class="external">https://github.com/shugo/jruby/pull/1</a></p>
<a name="Background"></a>
<h2 >Background<a href="#Background" class="wiki-anchor">¶</a></h2>
<p>I proposed <a href="https://bugs.ruby-lang.org/issues/12086" class="external">Feature #12086: using: option for instance_eval etc.</a> before, but it has problems:</p>
<ul>
<li>Thread safety: The same block can be invoked with different refinements in multiple threads, so it's hard to implement method caching.</li>
<li>_exec family support: {instance,class,module}_exec cannot be supported.</li>
<li>Implicit use of refinements: every blocks can be used with refinements, so there was implementation difficulty in JRuby and it has usability issue in headius's opinion.</li>
</ul>
<a name="Solutions-in-this-proposal"></a>
<h2 >Solutions in this proposal<a href="#Solutions-in-this-proposal" class="wiki-anchor">¶</a></h2>
<a name="Thread-safety"></a>
<h3 >Thread safety<a href="#Thread-safety" class="wiki-anchor">¶</a></h3>
<p>Proc#using affects the block represented by the Proc object, neither the specific Proc object nor the specific block invocation.<br>
Method calls in a block are resolved with refinements which are used by Proc#using in the block at the time.<br>
Once all possible refinements are used in the block, there is no need to invalidate method cache anymore.</p>
<p>See <a href="https://github.com/shugo/ruby/pull/2/commits/1c922614ad7d1fb43b73e195348c81da7a4546ef" class="external">these tests</a> to understand how it works.<br>
Which refinements are used is depending on the order of Proc#using invocations until all Proc#using calls are finished, but eventually method calls in a block are resolved with the same refinements.</p>
<a name="-_exec-family-support"></a>
<h3 >* _exec family support<a href="#-_exec-family-support" class="wiki-anchor">¶</a></h3>
<p><a href="https://bugs.ruby-lang.org/issues/12086" class="external">Feature #12086</a> was an extension of _eval family, so it cannot be used with _exec family, but Proc#using is independent from _eval family, and can be used with _exec family:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">instance_exec_with_integer_div_ext</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="n">block</span><span class="p">.</span><span class="nf">using</span><span class="p">(</span><span class="no">IntegerDivExt</span><span class="p">)</span>
<span class="n">obj</span><span class="p">.</span><span class="nf">instance_exec</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">using</span> <span class="no">Proc</span><span class="o">::</span><span class="no">Refinements</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> 0</span>
<span class="n">instance_exec_with_integer_div_ext</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="k">do</span> <span class="o">|</span><span class="n">other</span><span class="o">|</span>
<span class="nb">p</span> <span class="nb">self</span> <span class="o">/</span> <span class="n">other</span> <span class="c1">#=> (1/2)</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> 0</span>
</code></pre>
<a name="Implicit-use-of-refinements"></a>
<h3 >Implicit use of refinements<a href="#Implicit-use-of-refinements" class="wiki-anchor">¶</a></h3>
<p>Proc#using can be used only if <code>using Proc::Refinements</code> is called in the scope of the block represented by the Proc object.<br>
Otherwise, a RuntimeError is raised.</p>
<p>There are two reasons:</p>
<ul>
<li>JRuby creates a special CallSite for refinements at compile-time only when <code>using</code> is called at the scope.</li>
<li>When reading programs, it may help understanding behavior. IMHO, it may be unnecessary if libraries which uses Proc#using are well documented.</li>
</ul>
<p><code>Proc::Refinements</code> is a dummy module, and has no actual refinements.</p> Ruby master - Feature #16350 (Assigned): ArithmeticSequence#member? can result in infinite loophttps://bugs.ruby-lang.org/issues/163502019-11-16T17:20:32Zparker (Parker Finch)
<p>I'm not sure if this is a bug or a feature, it feels somewhere in between.</p>
<p>This is my first time contributing to the Ruby code, let me know what I can improve in this report!</p>
<p>ArithmeticSequence#member? enumerates through the sequence in order to determine if an element is included. (It just uses Enumerable#member?.) This leads to an infinite loop if the sequence is infinite and the element is not included, such as <code>1.step.member?(0)</code>.</p>
<p>I expected <code>1.step.member?(0)</code> to return <code>false</code>.</p>
<p>Since ArithmeticSequences are much more constrained than regular Enumerables, the #member? method can be overridden to efficiently determine if an element is included in the sequence.</p>
<p>I started implementing this change (patch attached) but got a little confused when trying to handle floats. Before digging in too deeply, I wanted to check if this is a change that will be accepted.</p>
<p>Let me know if I should keep looking into this!</p> Ruby master - Misc #16025 (Assigned): 'st_check_for_sizeof_st_index_t' declared as array with a n...https://bugs.ruby-lang.org/issues/160252019-07-27T05:32:44Zvadimp (Vadim Peretokin)
<p>Compilation of st.h with Emscripten 1.38.30 fails:</p>
<pre><code class="c syntaxhl" data-language="c"><span class="n">st</span><span class="p">.</span><span class="n">h</span><span class="o">:</span><span class="mi">65</span><span class="o">:</span><span class="mi">45</span><span class="o">:</span> <span class="n">error</span><span class="o">:</span> <span class="err">'</span><span class="n">st_check_for_sizeof_st_index_t</span><span class="err">'</span> <span class="n">declared</span> <span class="n">as</span> <span class="n">an</span>
<span class="n">array</span> <span class="n">with</span> <span class="n">a</span> <span class="n">negative</span> <span class="n">size</span>
<span class="k">typedef</span> <span class="kt">char</span> <span class="n">st_check_for_sizeof_st_index_t</span><span class="p">[</span><span class="n">SIZEOF_VOIDP</span> <span class="o">==</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="k">sizeof</span><span class="p">(</span><span class="n">st_index_t</span><span class="p">)</span> <span class="o">?</span> <span class="mi">1</span> <span class="o">:</span> <span class="o">-</span><span class="mi">1</span><span class="p">];</span>
<span class="o">^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span>
<span class="mi">3</span><span class="n">rdparty</span><span class="o">/</span><span class="n">edbee</span><span class="o">-</span><span class="n">lib</span><span class="o">/</span><span class="n">vendor</span><span class="o">/</span><span class="n">onig</span><span class="o">/</span><span class="n">config</span><span class="p">.</span><span class="n">h</span><span class="o">:</span><span class="mi">109</span><span class="o">:</span><span class="mi">22</span><span class="o">:</span> <span class="n">note</span><span class="o">:</span> <span class="n">expanded</span> <span class="n">from</span> <span class="n">macro</span> <span class="err">'</span><span class="n">SIZEOF_VOIDP</span><span class="err">'</span>
<span class="cp">#define SIZEOF_VOIDP 8
</span> <span class="o">^</span>
<span class="mi">1</span> <span class="n">error</span> <span class="n">generated</span><span class="p">.</span>
<span class="n">shared</span><span class="o">:</span><span class="n">ERROR</span><span class="o">:</span> <span class="n">compiler</span> <span class="n">frontend</span> <span class="n">failed</span> <span class="n">to</span> <span class="n">generate</span> <span class="n">LLVM</span> <span class="n">bitcode</span><span class="p">,</span> <span class="n">halting</span>
<span class="n">Makefile</span><span class="o">:</span><span class="mi">36871</span><span class="o">:</span> <span class="n">recipe</span> <span class="k">for</span> <span class="n">target</span> <span class="err">'</span><span class="n">regcomp</span><span class="p">.</span><span class="n">o</span><span class="err">'</span> <span class="n">failed</span>
</code></pre>
<p>Both sizeof are set to 8:</p>
<pre><code class="c syntaxhl" data-language="c"><span class="n">onig</span><span class="err">$</span> <span class="n">cat</span> <span class="n">config</span><span class="p">.</span><span class="n">h</span> <span class="o">|</span> <span class="n">grep</span> <span class="n">SIZEOF_LONG</span>
<span class="cp">#define SIZEOF_LONG 8
#define SIZEOF_LONG_LONG 8
</span></code></pre>
<p>Is there a way to fix this issue or add a workaround for emscripten (<code>__EMSCRIPTEN__</code>)?</p> Ruby master - Misc #15806 (Assigned): Explicitly initialise encodings on init to remove branches ...https://bugs.ruby-lang.org/issues/158062019-04-27T23:41:34Zmethodmissing (Lourens Naudé)lourens@bearmetal.eu
<p>References Github PR <a href="https://github.com/ruby/ruby/pull/2128" class="external">https://github.com/ruby/ruby/pull/2128</a></p>
<p>I noticed that the encoding table is loaded on startup of even just <code>miniruby</code> (minimal viable interpreter use case) through this backtrace during ruby setup:</p>
<pre><code>/home/lourens/src/ruby/ruby/miniruby(rb_enc_init+0x12) [0x56197b0c0c72] encoding.c:587
/home/lourens/src/ruby/ruby/miniruby(rb_usascii_encoding+0x1a) [0x56197b0c948a] encoding.c:1357
/home/lourens/src/ruby/ruby/miniruby(Init_sym+0x7a) [0x56197b24810a] symbol.c:42
/home/lourens/src/ruby/ruby/miniruby(rb_call_inits+0x1d) [0x56197b11afed] inits.c:25
/home/lourens/src/ruby/ruby/miniruby(ruby_setup+0xf6) [0x56197b0ec9d6] eval.c:74
/home/lourens/src/ruby/ruby/miniruby(ruby_init+0x9) [0x56197b0eca39] eval.c:91
/home/lourens/src/ruby/ruby/miniruby(main+0x5a) [0x56197b051a2a] ./main.c:41
</code></pre>
<p>Therefore I think it makes sense to instead initialize encodings explicitly just prior to symbol init, which is the first entry point into the interpreter loading that currently triggers <code>rb_enc_init</code> and remove the initialization check branches from the various lookup methods.</p>
<p>Some of the branches collapsed, <code>cachegrind</code> output, columns are <code>Ir Bc Bcm Bi Bim</code> with <code>Ir</code> (instructions retired), <code>Bc</code> (branches taken) and <code>Bcm</code> (branches missed) relevant here as there are no indirect branches (function pointers etc.):</p>
<p>(hot function, many instructions retired and branches taken and missed)</p>
<pre><code> . . . . . rb_encoding *
. . . . . rb_enc_from_index(int index)
835,669 0 0 0 0 {
13,133,536 6,337,652 50,267 0 0 if (!enc_table.list) {
3 0 0 0 0 rb_enc_init();
. . . . . }
23,499,349 8,006,202 293,161 0 0 if (index < 0 || enc_table.count <= (index &= ENC_INDEX_MASK)) {
. . . . . return 0;
. . . . . }
30,024,494 0 0 0 0 return enc_table.list[index].enc;
1,671,338 0 0 0 0 }
</code></pre>
<p>(cold function, representative of the utf8 variant more or less too)</p>
<pre><code> . . . . . rb_encoding *
. . . . . rb_ascii8bit_encoding(void)
. . . . . {
27,702 9,235 955 0 0 if (!enc_table.list) {
. . . . . rb_enc_init();
. . . . . }
9,238 0 0 0 0 return enc_table.list[ENCINDEX_ASCII].enc;
9,232 0 0 0 0 }
</code></pre>
<p>I think lazy loading encodings and populating the table is fine, but initializing it can be done more explicitly in the boot process.</p> Ruby master - Feature #15239 (Assigned): [patch] test-spec win32olehttps://bugs.ruby-lang.org/issues/152392018-10-20T19:32:07ZMSP-Greg (Greg L)
<p>Some of the current Win32OLE spec tests use the InternetExplorer control. This control is not available on Azure pipelines. Attached patch changes to use the MSXML control, adds a guard for it, and also does some refactoring to lower requires when not run under Windows, etc. Also, since the MSXML object is quite a bit 'smaller' than InternetExplorer, tests run faster.</p>
<p>Passed in my fork at <a href="https://ci.appveyor.com/project/MSP-Greg/ruby/builds/19663145" class="external">https://ci.appveyor.com/project/MSP-Greg/ruby/builds/19663145</a></p>
<p>Note also that since there have been recent commits stabilizing the spec suite, the above build job changed the mswin spec tests to run parallel, and they passed. The change from serial to parallel is not included in the patches. It is a separate commit in the branch on my fork.</p>
<p>GitHub patch is at:<br>
<a href="https://github.com/MSP-Greg/ruby/commit/d1daf9a66f491abfac5e84a50f152505baa1ccac.patch" class="external">https://github.com/MSP-Greg/ruby/commit/d1daf9a66f491abfac5e84a50f152505baa1ccac.patch</a></p> Ruby master - Feature #15166 (Assigned): 2.5 times faster implementation than current gcd implmen...https://bugs.ruby-lang.org/issues/151662018-09-26T18:30:29Zjzakiya (Jabari Zakiya)
<p>This is to be more explicit (and accurate) than <a href="https://bugs.ruby-lang.org/issues/15161" class="external">https://bugs.ruby-lang.org/issues/15161</a></p>
<p>This is my modified gcd benchmarks code, originally presented by Daniel Lemire (see 15161).</p>
<p><a href="https://gist.github.com/jzakiya/44eae4feeda8f6b048e19ff41a0c6566" class="external">https://gist.github.com/jzakiya/44eae4feeda8f6b048e19ff41a0c6566</a></p>
<p>Ruby's current implementation of Stein's gcd algorithm is only slightly faster than the<br>
code posted on the wikepedia page, and over 2.5 times slower than the fastest implementation<br>
in the benchmarks.</p>
<pre><code>[jzakiya@localhost ~]$ ./gcdbenchmarks
gcd between numbers in [1 and 2000]
gcdwikipedia7fast32 : time = 99
gcdwikipedia4fast : time = 121
gcdFranke : time = 126
gcdwikipedia3fast : time = 134
gcdwikipedia2fastswap : time = 136
gcdwikipedia5fast : time = 139
gcdwikipedia7fast : time = 138
gcdwikipedia2fast : time = 136
gcdwikipedia6fastxchg : time = 144
gcdwikipedia2fastxchg : time = 156
gcd_iterative_mod : time = 210
gcd_recursive : time = 215
basicgcd : time = 211
rubygcd : time = 267
gcdwikipedia2 : time = 321
gcd between numbers in [1000000001 and 1000002000]
gcdwikipedia7fast32 : time = 100
gcdwikipedia4fast : time = 121
gcdFranke : time = 126
gcdwikipedia3fast : time = 134
gcdwikipedia2fastswap : time = 136
gcdwikipedia5fast : time = 138
gcdwikipedia7fast : time = 138
gcdwikipedia2fast : time = 136
gcdwikipedia6fastxchg : time = 144
gcdwikipedia2fastxchg : time = 156
gcd_iterative_mod : time = 210
gcd_recursive : time = 215
basicgcd : time = 211
rubygcd : time = 269
gcdwikipedia2 : time = 323
</code></pre>
<p>This is Ruby's code per: <a href="https://github.com/ruby/ruby/blob/3abbaab1a7a97d18f481164c7dc48749b86d7f39/rational.c#L285-L307" class="external">https://github.com/ruby/ruby/blob/3abbaab1a7a97d18f481164c7dc48749b86d7f39/rational.c#L285-L307</a><br>
which is basically the wikepedia implementation.</p>
<pre><code>inline static long
i_gcd(long x, long y)
{
unsigned long u, v, t;
int shift;
if (x < 0)
x = -x;
if (y < 0)
y = -y;
if (x == 0)
return y;
if (y == 0)
return x;
u = (unsigned long)x;
v = (unsigned long)y;
for (shift = 0; ((u | v) & 1) == 0; ++shift) {
u >>= 1;
v >>= 1;
}
while ((u & 1) == 0)
u >>= 1;
do {
while ((v & 1) == 0)
v >>= 1;
if (u > v) {
t = v;
v = u;
u = t;
}
v = v - u;
} while (v != 0);
return (long)(u << shift);
}
</code></pre>
<p>This is the fastest implementation from the benchmarks. (I originally, wrongly, cited<br>
the implementation in the article, which is 4|5th fastest in benchmarks, but<br>
still almost 2x faster than the Ruby implementation.)</p>
<pre><code>// based on wikipedia's article,
// fixed by D. Lemire, K. Willets
unsigned int gcdwikipedia7fast32(unsigned int u, unsigned int v)
{
int shift, uz, vz;
if ( u == 0) return v;
if ( v == 0) return u;
uz = __builtin_ctz(u);
vz = __builtin_ctz(v);
shift = uz > vz ? vz : uz;
u >>= uz;
do {
v >>= vz;
int diff = v;
diff -= u;
if ( diff == 0 ) break;
vz = __builtin_ctz(diff);
if ( v < u ) u = v;
v = abs(diff);
} while( 1 );
return u << shift;
}
</code></pre>
<p>The key to speeding up all the algorithms is using the <code>__builtin_ctz(x)</code> directive<br>
to determine the number of trailing binary '0's.</p> Ruby master - Feature #14901 (Assigned): [PATCH] do not block SIGCHLD in normal Ruby Threadshttps://bugs.ruby-lang.org/issues/149012018-07-08T02:53:23Znormalperson (Eric Wong)normalperson@yhbt.net
<p><a class="user active user-mention" href="https://bugs.ruby-lang.org/users/10073">@k0kubun (Takashi Kokubun)</a>: any opinions on this? Thanks.</p>
<pre><code>I blocked SIGCHLD in normal Ruby Threads for [Bug #14867]
because I noticed at least two places which could not deal
with spurious wakeups in our test suite.
I also want to get rid of timer-thread due to resource
limitations <a href="https://blade.ruby-lang.org/ruby-core/87773">[ruby-core:87773]</a>. MJIT causes many SIGCHLD signals
so I found the following problems with cppflags=-DMJIT_FORCE_ENABLE=1
* OpenSSL::PKey::*.new does not resume on handle signals.
rhenium acknowledged the problem and it should be in trunk soon:
https://bugs.ruby-lang.org/issues/14882
* test/-ext-/gvl/test_last_thread.rb does not handle spurious
wakeups. Original report is in Japanese:
https://bugs.ruby-lang.org/issues/11237
I don't think it's a realistic expectation for code to be
unable to deal with spurious wakeups.
One alternative could be to handle signals with MJIT thread
when MJIT is enabled, or to lazy-spawn timer thread to handle
signals when MJIT is enabled (MJIT + gcc requires a lot of
resources, anyways).
</code></pre> Ruby master - Feature #14476 (Assigned): Adding same_all? for checking whether all items in an Ar...https://bugs.ruby-lang.org/issues/144762018-02-14T15:41:30Zmrkn (Kenta Murata)muraken@gmail.com
<p>In this issue, I propose to introduce <code>same_all?</code> instance method of <code>Array</code> class. This new method checks whether all items in the receiver are the same.</p>
<p>Today, I needed to write a code to judge whether all items in an <code>Array</code> are the same. I wanted to make the following expression, which I've written first, more efficient.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">ary</span><span class="p">.</span><span class="nf">all?</span> <span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="n">e</span><span class="p">.</span><span class="nf">foo</span> <span class="o">==</span> <span class="n">ary</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nf">foo</span> <span class="p">}</span>
</code></pre>
<p>I considered about the following simpler case, too.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">ary</span><span class="p">.</span><span class="nf">all?</span> <span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="n">e</span> <span class="o">==</span> <span class="n">ary</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="p">}</span>
</code></pre>
<p>As I discussed with some CRuby committers and my colleagues at Speee, Inc., I found that both cases can be written more efficiently as follows:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># for the 1st case</span>
<span class="n">ary</span><span class="p">.</span><span class="nf">empty?</span> <span class="o">||</span> <span class="n">ary</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nf">foo</span><span class="p">.</span><span class="nf">yield_self</span> <span class="p">{</span><span class="o">|</span><span class="n">e0</span><span class="o">|</span> <span class="n">ary</span><span class="p">[</span><span class="mi">1</span><span class="o">..-</span><span class="mi">1</span><span class="p">].</span><span class="nf">all?</span> <span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="n">e</span><span class="p">.</span><span class="nf">foo</span> <span class="o">==</span> <span class="n">e0</span> <span class="p">}</span> <span class="p">}</span><span class="err"> </span>
<span class="c1"># for the 2nd case</span>
<span class="n">ary</span><span class="p">.</span><span class="nf">empty?</span> <span class="o">||</span> <span class="n">ary</span><span class="p">[</span><span class="mi">0</span><span class="o">..-</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="n">ary</span><span class="p">[</span><span class="mi">1</span><span class="o">..-</span><span class="mi">1</span><span class="p">]</span>
</code></pre>
<p>However, it is not easy to understand the intent of either expression, which is to check whether all items are the same.</p>
<p>I want to give this feature a clear name to make code readable. And I think it should be provided as a core feature because it can be made more efficient by being implemented in C language.</p>
<p>The benchmark script is: <a href="https://gist.github.com/mrkn/26a0fcfc431a45fe809fbbef95aceaf5" class="external">https://gist.github.com/mrkn/26a0fcfc431a45fe809fbbef95aceaf5</a><br>
I used it to find the efficient expressions. The example result of this benchmark on my MacBook Pro is here.</p>
<pre><code>$ ruby -v bench.rb
ruby 2.6.0dev (2018-02-14 trunk 62402) [x86_64-darwin16]
----------------------------------------
Benchmark case: shuffle
user system total real
all?-method-1 0.001525 0.000088 0.001613 ( 0.001632)
all?-method-2 0.000489 0.000031 0.000520 ( 0.000565)
all?-method-3 0.000444 0.000039 0.000483 ( 0.000482)
all?-item 0.000325 0.000078 0.000403 ( 0.000402)
opt-method 0.655959 0.033814 0.689773 ( 0.708515)
opt-item 0.000316 0.000001 0.000317 ( 0.000317)
----------------------------------------
Benchmark case: tail0
user system total real
all?-method-1 9.412810 0.231126 9.643936 ( 9.681118)
all?-method-2 5.375075 0.137908 5.512983 ( 5.754550)
all?-method-3 5.226132 0.167640 5.393772 ( 5.507031)
all?-item 0.873700 0.007545 0.881245 ( 0.917210)
opt-method 5.319648 0.172547 5.492195 ( 5.633140)
opt-item 0.174349 0.001974 0.176323 ( 0.183002)
----------------------------------------
Benchmark case: head0
user system total real
all?-method-1 0.002421 0.000068 0.002489 ( 0.002489)
all?-method-2 0.002169 0.000213 0.002382 ( 0.002382)
all?-method-3 0.001624 0.000026 0.001650 ( 0.001651)
all?-item 0.000623 0.000001 0.000624 ( 0.000624)
opt-method 4.779120 0.146312 4.925432 ( 4.951167)
opt-item 0.000629 0.000001 0.000630 ( 0.000629)
----------------------------------------
Benchmark case: all1
user system total real
all?-method-1 9.379650 0.255865 9.635515 ( 9.683078)
all?-method-2 4.950280 0.150659 5.100939 ( 5.140174)
all?-method-3 4.857898 0.129125 4.987023 ( 5.003142)
all?-item 0.694113 0.001295 0.695408 ( 0.702370)
opt-method 5.032373 0.121708 5.154081 ( 5.189599)
opt-item 0.170540 0.002069 0.172609 ( 0.180343)
</code></pre> Ruby master - Feature #14412 (Assigned): DRb UNIX on local machine: add support for getpeereid()https://bugs.ruby-lang.org/issues/144122018-01-27T17:26:32ZAnonymous
<p>Hi,</p>
<p><code>UNIXSocket</code> has this method <code>#getpeereid()</code> which returns effective user ID and effective group ID.</p>
<p>DRb using <code>drbunix://</code> on local machine doesn't support that method. In my use case, I need to verify clients via that method. So it would be great if you add support to DRb.</p>
<p>Actually that method <code>#getpeereid()</code> is from <code>BaseSocket</code>, but documentation states that it only supports UNIX sockets. I mean, it's a general method from parent class. So you can do the same with DRb: add some similar method, but only works via <code>drbunix://</code> on local machine. Otherwise you can raise error...</p>
<p>Thank you,</p> Ruby master - Feature #14397 (Assigned): public, protected and private should return their argume...https://bugs.ruby-lang.org/issues/143972018-01-24T21:27:26Zusa (Usaku NAKAMURA)usa@garbagecollect.jp
<p>Matsuda-san suggested me that <code>public</code>, <code>protected</code> and <code>private</code> should return their arguments instead of <code>self</code>,<br>
to write such code:`</p>
<pre><code class="Ruby syntaxhl" data-language="Ruby"><span class="nb">require</span> <span class="s2">"finalist"</span>
<span class="c1"># see https://github.com/joker1007/finalist</span>
<span class="k">class</span> <span class="nc">Foo</span>
<span class="kp">extend</span> <span class="no">Finalist</span>
<span class="n">final</span> <span class="kp">private</span> <span class="k">def</span> <span class="nf">foo</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>I believe that it's reasonable request, and also believe that there is no product code which uses the return values of <code>public</code>, <code>protected</code> and <code>private</code>.<br>
Matz, how do you think about this change?<br>
The patch is attached.</p> Ruby master - Misc #13622 (Assigned): Documentation missinghttps://bugs.ruby-lang.org/issues/136222017-06-02T14:08:27Zsergzhum (Sergey Zhumatiy)
<p>In documentation for method IO.nread important information is missing: you must do 'require "io/wait"' before using it. May be some other methods of IO in 'io/wait' are missed this IMPORTANT notice.</p> Ruby master - Feature #13577 (Assigned): Digest.file accidentally receives File object but uses f...https://bugs.ruby-lang.org/issues/135772017-05-19T09:03:19Znaruse (Yui NARUSE)naruse@airemix.jp
<p>Digest::SHA256.file()'s first argument is file path name but it accidentally accepts file object.<br>
But for file objects created with O_TMPFILE to_path returns the directory of the temporary file and this File.open will fail.</p>
<pre><code> class ::Digest::Class
# Creates a digest object and reads a given file, _name_.
# Optional arguments are passed to the constructor of the digest
# class.
#
# p Digest::SHA256.file("X11R6.8.2-src.tar.bz2").hexdigest
# # => "f02e3c85572dc9ad7cb77c2a638e3be24cc1b5bea9fdbb0b0299c9668475c534"
def self.file(name, *args)
new(*args).file(name)
end
end
module Instance
# Updates the digest with the contents of a given file _name_ and
# returns self.
def file(name)
File.open(name, "rb") {|f|
buf = ""
while f.read(16384, buf)
update buf
end
}
self
end
</code></pre> Ruby master - Feature #13516 (Assigned): Improve the text of the circular require warninghttps://bugs.ruby-lang.org/issues/135162017-04-27T22:41:20Zjaredbeck (Jared Beck)jared@jaredbeck.com
<p>The warning currently reads:</p>
<p><code>loading in progress, circular require considered harmful - /my/file.rb</code></p>
<p>I think it would be more helpful like:</p>
<p><code>Circular require: Loading of /my/file.rb is already in progress, but require was called again</code></p>
<p>I think this is more helpful because it clarifies that /my/file.rb is the problem.</p>
<p>What do you think? Thanks!</p> Ruby master - Feature #13129 (Assigned): Refinements cannot refine method_missing and respond_to_...https://bugs.ruby-lang.org/issues/131292017-01-14T17:21:59Zmatsuda (Akira Matsuda)ronnie@dio.jp
<p>Refinements with method_missing and respond_to_missing? behaves very strangely.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">C</span><span class="p">;</span> <span class="k">end</span>
<span class="n">using</span> <span class="no">Module</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span>
<span class="n">refine</span> <span class="no">C</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">x</span><span class="p">()</span> <span class="nb">p</span><span class="ss">:x</span><span class="p">;</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="n">m</span> <span class="o">==</span> <span class="ss">:foo</span> <span class="p">?</span> <span class="nb">p</span><span class="p">(</span><span class="ss">:fooo!</span><span class="p">)</span> <span class="p">:</span> <span class="k">super</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">respond_to_missing?</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">include_private</span> <span class="o">=</span> <span class="kp">false</span><span class="p">)</span>
<span class="p">(</span><span class="n">m</span> <span class="o">==</span> <span class="ss">:foo</span><span class="p">)</span> <span class="o">||</span> <span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="p">}</span>
<span class="no">C</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">x</span>
<span class="nb">p</span> <span class="no">C</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">respond_to?</span> <span class="ss">: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>
</code></pre>
<p>The script above doesn't respond_to :foo nor run :foo as expected.<br>
Actually, the result differs between ruby versions.</p>
<pre><code>% ruby -v t.rb
ruby 2.5.0dev (2017-01-14 trunk 57328) [x86_64-darwin15]
:x
false
t.rb:19:in `<main>': undefined method `foo' for #<C:0x007f90ca0fb240> (NoMethodError)
% ruby -v t.rb
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin15]
:x
false
t.rb:19:in `<main>': undefined method `foo' for #<C:0x007f80ae097780> (NoMethodError)
% ruby -v t.rb
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin15]
:x
false
t.rb:19:in `<main>': undefined method `foo' for #<C:0x007fd89c83b518> (NoMethodError)
% ruby -v t.rb
ruby 2.2.6p396 (2016-11-15 revision 56800) [x86_64-darwin15]
:x
false
:fooo!
% ruby -v t.rb
ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-darwin15.0]
:x
false
:fooo!
% ruby -v t.rb
ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-darwin15.6.0]
t.rb:4: warning: Refinements are experimental, and the behavior may change in future versions of Ruby!
:x
false
:fooo!
</code></pre>
<p>What I can tell is that method_missing was broken at somewhere in between 2.2 and 2.3, and respond_to_missing? has never worked correctly.</p> Ruby master - Bug #12725 (Assigned): Trying to use ./miniruby before it existshttps://bugs.ruby-lang.org/issues/127252016-09-05T05:04:23Zduerst (Martin Dürst)duerst@it.aoyama.ac.jpRuby master - Feature #12653 (Assigned): Use wide WinAPI for rb_w32_getcwdhttps://bugs.ruby-lang.org/issues/126532016-08-03T18:33:23Zdavispuh (Dāvis Mosāns)
<p>Use wide WinAPI for rb_w32_getcwd.<br>
This will be needed so that Dir.pwd can support Unicode current directory on Windows.</p>
<p>I've attached a patch.</p> Ruby master - Bug #12582 (Assigned): OpenSSL Authenticated Encryption should check for tag lengthhttps://bugs.ruby-lang.org/issues/125822016-07-11T07:35:30Zpatrick.oscity (Patrick Oscity)
<p>The current API for using ciphers with Authenticated Encryption (currently only AES-GCM) is rather misleading and quickly leads to subtle bugs related to the length of <code>auth_tag</code>.</p>
<p>In particular, the current implementation will <em>not</em> check for the length of the <code>auth_tag</code>. Because GCM mode allows arbitrary sizes of the <code>auth_tag</code> up to 128 bytes, only a single byte needs to be supplied to make the authentication pass. This means that an attacker needs at most 256 attempts in order to forge a valid <code>auth_tag</code>.</p>
<pre><code>data = 'secret'
cipher = OpenSSL::Cipher.new('aes-128-gcm')
cipher.encrypt
key = cipher.random_key
iv = cipher.random_iv
cipher.auth_data = 'auth_data'
ciphertext = cipher.update(data) + cipher.final
auth_tag = cipher.auth_tag
auth_tag = auth_tag[0] # single byte is sufficient
cipher = OpenSSL::Cipher.new('aes-128-gcm')
cipher.decrypt
cipher.key = key
cipher.iv = iv
cipher.auth_tag = auth_tag
cipher.auth_data = 'auth_data'
data = cipher.update(ciphertext) + cipher.final
# NO error raised
</code></pre>
<p>Currently, the only way to prevent such attacks is to manually assert the correct <code>auth_tag</code> length when decrypting/authenticating.</p>
<pre><code>raise 'incorrect auth_tag length' unless auth_tag.length == 16
</code></pre>
<p>I suggest the following improvements:</p>
<a name="Documentation-should-mention-the-importance-of-manually-checking-auth_tag-length"></a>
<h3 >Documentation should mention the importance of manually checking <code>auth_tag</code> length<a href="#Documentation-should-mention-the-importance-of-manually-checking-auth_tag-length" class="wiki-anchor">¶</a></h3>
<p>This can/should be done immediately even if the API should not change.</p>
<a name="Authentication-tag-length-should-be-an-input-parameter-to-the-cipher"></a>
<h3 >Authentication tag length should be an input parameter to the cipher<a href="#Authentication-tag-length-should-be-an-input-parameter-to-the-cipher" class="wiki-anchor">¶</a></h3>
<p>To improve the usability of the API and unburden users from performing additional manual checks without compromising security, I suggest to add an <code>auth_tag_len</code> accessor. This can be used to determine the size of the <code>auth_tag</code> both when generating and when authenticating the <code>auth_tag</code>. The default value should be 16 bytes (see below).</p>
<h3>
<code>#auth_tag</code> should use <code>auth_tag_len</code> to determine the output length</h3>
<p>During encryption:</p>
<p>If no parameter is given, <code>#auth_tag</code> should return an authentication tag according to the length configured in <code>auth_tag_len</code>.</p>
<p>If a length parameter is given, <code>#auth_tag</code> should use the supplied parameter to determine the length of the authentication tag. Although this parameter is not as useful any more it should be kept for backwards compatibility. Maybe it should be deprecated.</p>
<p>Currently the API supports different tag lengths by passing the length parameter to <code>#auth_tag</code>. This currently defaults to 16 bytes, which should be the default value for <code>auth_tag_len</code> in order to keep backwards compatibility.</p>
<h3>
<code>#final</code> should use <code>auth_tag_len</code> to assert the correct length of the <code>auth_tag</code>
</h3>
<p>During decryption:</p>
<p><code>auth_tag_len</code> should be used to assert that the supplied <code>auth_tag</code> has the correct length. The big difference to the existing API lies here, because users need to actively change the value of <code>auth_tag_len</code> in order to allow shorter tags.</p>
<p>When the check fails, an <code>OpenSSL::Cipher::CipherError</code> should be raised. The same type of error is already raised when authentication fails, so existing users should be fine without having to touch their error handling. A descriptive error message should be helpful. In order to distinguish between such errors and "actual" verification errors, we could also add a descriptive message for the latter.</p>
<p>I'd be happy to implement these changes, but I wanted to discuss them first.</p> Ruby master - Feature #12281 (Assigned): Allow lexically scoped use of refinements with `using {}...https://bugs.ruby-lang.org/issues/122812016-04-14T03:48:01Zdanielpclark (Daniel P. Clark)6ftdan@gmail.com
<p>In Ruby 2.2.3 a refinement could be used in a begin/end block.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">Moo</span>
<span class="n">refine</span> <span class="no">Fixnum</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">to_s</span>
<span class="s2">"moo"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">begin</span> <span class="c1"># valid Ruby 2.2.3 and NOT Ruby 2.3</span>
<span class="n">using</span> <span class="no">Moo</span>
<span class="mi">1</span><span class="p">.</span><span class="nf">to_s</span>
<span class="k">end</span>
<span class="c1"># => "moo"</span>
</code></pre>
<p>Since this use case has been removed I would like to propose an alternative.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">using</span> <span class="no">Moo</span> <span class="k">do</span>
<span class="mi">1</span><span class="p">.</span><span class="nf">to_s</span>
<span class="k">end</span>
<span class="c1"># => "moo"</span>
</code></pre>
<p>I would like to propose allowing refinements to take a block and perform the refinement within the block and work just as if it were in it's own lexically scoped class.</p>
<p>I've been writing a lot of Rust lately and have found that their way of implementing Traits is just like Ruby's refinements except for that you can use Rust's version of refinements anywhere. Since Ruby's implementation is strictly lexically scoped I merely suggest a block syntax for <code>using</code> to allow greater expansion of refinements.</p>
<pre><code class="rust syntaxhl" data-language="rust"><span class="c1">// Rust</span>
<span class="k">impl</span> <span class="n">MyCapitalize</span> <span class="k">for</span> <span class="nb">String</span> <span class="p">{</span>
<span class="k">fn</span> <span class="nf">my_capitalize</span><span class="p">(</span><span class="o">&</span><span class="k">self</span><span class="p">)</span> <span class="k">-></span> <span class="k">Self</span> <span class="p">{</span>
<span class="c1">// code here</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">use</span> <span class="n">MyCapitalize</span><span class="p">;</span>
<span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"hello"</span><span class="p">)</span><span class="nf">.my_capitalize</span><span class="p">()</span>
</code></pre>
<p>Rust lets you use the "refinement" of the trait implementation anywhere you use <code>use</code> just like Ruby's <code>using</code>. But currently Ruby restricts where <code>using</code> can be used. I would like that restriction to be lifted by allowing <code>using</code> to take a block.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># Ruby</span>
<span class="k">module</span> <span class="nn">MyCapitalize</span>
<span class="n">refine</span> <span class="no">String</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">my_capitalize</span>
<span class="c1"># code here</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">using</span> <span class="no">MyCapitalize</span> <span class="k">do</span>
<span class="s2">"hello"</span><span class="p">.</span><span class="nf">my_capitalize</span>
<span class="k">end</span>
<span class="c1"># => "Hello"</span>
</code></pre>
<p>This way we keep Ruby's strict lexical scope behavior and at the same time allow refinement usage anywhere we need it.</p> Ruby master - Feature #11955 (Assigned): Expose Object that Receives logs in Loggerhttps://bugs.ruby-lang.org/issues/119552016-01-05T21:59:29Zschneems (Richard Schneeman)
<p>I need to be able to perform logic based on the destination of a current logger, this is currently not possible without <code>instance_variable_get</code>. Why would you need to see what destination a logger is going to? There is a common pattern in long lived programs like webservers. You want logs on disk for later reference, but you also want them in STDOUT to make development and debugging easier. Rails does this in development mode. Since there is no way to see if a logger is already going to STDOUT, it gets extended to log to STDOUT so logs show up twice.</p>
<p>While that example was complicated the logic I want is very simple: if you have a logger that is logging to STDOUT, do nothing, otherwise log to STDOUT and current logger. You cannot do this today without exposing the destination of the logger. This patch exposes the logger destination and allows us to write code like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">make_sure_logging_to_stdout</span><span class="p">(</span><span class="n">logger</span><span class="p">)</span>
<span class="k">unless</span> <span class="n">logger</span><span class="p">.</span><span class="nf">destination</span> <span class="o">==</span> <span class="no">STDOUT</span> <span class="c1"># <==== Cannot do this today</span>
<span class="n">stdout_logger</span> <span class="o">=</span> <span class="o">::</span><span class="no">Logger</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">STDOUT</span><span class="p">)</span>
<span class="n">logger</span><span class="p">.</span><span class="nf">extend</span><span class="p">(</span><span class="no">Module</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">add</span><span class="p">((</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="n">stdout_logger</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="k">super</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">logger</span> <span class="o">=</span> <span class="no">Logger</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">STDOUT</span><span class="p">)</span>
<span class="n">make_sure_logging_to_stdout</span><span class="p">(</span><span class="n">logger</span><span class="p">)</span>
<span class="n">logger</span><span class="p">.</span><span class="nf">fatal</span><span class="p">(</span><span class="s2">"An error has occured"</span><span class="p">)</span>
</code></pre>
<p>We should be able to inspect the destination of a logger, this patch enables this functionality.</p> Ruby master - Feature #11816 (Assigned): Partial safe navigation operatorhttps://bugs.ruby-lang.org/issues/118162015-12-14T18:19:37Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>I'm extremely surprised (and disappointed) that, currently:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">x</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="n">x</span><span class="o">&</span><span class="p">.</span><span class="nf">foo</span><span class="p">.</span><span class="nf">bar</span> <span class="c1"># => NoMethodError: undefined method `bar' for nil:NilClass</span>
</code></pre>
<p>To make it safe, you have to write <code>x&.foo&.bar</code>. But if <code>foo</code> is never supposed to return <code>nil</code>, then that code isn't "fail early" in case it actually does. <code>nil&.foo.bar</code> is more expressive, simpler and is perfect if you want to an error if <code>foo</code> returned <code>nil</code>. To actually get what you want, you have to resort using the old form <code>x && x.foo.bar</code>...</p>
<p>In CoffeeScript, you can write <code>x()?.foo.bar</code> and it will work well, since it gets compiled to</p>
<pre><code class="js syntaxhl" data-language="js"><span class="k">if </span><span class="p">((</span><span class="nx">_ref</span> <span class="o">=</span> <span class="nf">x</span><span class="p">())</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">_ref</span><span class="p">.</span><span class="nx">foo</span><span class="p">.</span><span class="nx">bar</span><span class="p">;</span>
<span class="p">}</span>
</code></pre>
<p>All the discussion in <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Introduce "Safe navigation operator" (Closed)" href="https://bugs.ruby-lang.org/issues/11537">#11537</a> focuses on <code>x&.foo&.bar</code>, so I have to ask:</p>
<p>Matz, what is your understanding of <code>x&.foo.bar</code>?</p>
<p>I feel the current implementation is not useful and should be changed to what I had in mind. I can't see any legitimate use of <code>x&.foo.bar</code> currently.</p> Ruby master - Feature #11625 (Assigned): Unlock GVL for SHA1 calculationshttps://bugs.ruby-lang.org/issues/116252015-10-27T19:34:06Ztenderlovemaking (Aaron Patterson)tenderlove@ruby-lang.org
<p>I'm trying to calculate many sha1 checksums, but the current sha1 implementation doesn't unlock the GVL, so I can't do it in parallel. I've attached a patch that unlocks the GVL when calculating sha1sums so that I can do them in parallel.</p>
<p>The good point about this patch is that I can calculate sha1's in parallel. Here is the test code I'm using:</p>
<pre><code>require 'digest/sha1'
require 'thread'
Thread.abort_on_exception = true
THREADS = (ENV['THREADS'] || 1).to_i
store = 'x' * (ENV['SIZE'] || 1024).to_i
queue = Queue.new
600000.times do
queue << store
end
THREADS.times { queue << nil }
ts = THREADS.times.map {
Thread.new {
while work = queue.pop
Digest::SHA1.hexdigest(work)
end
}
}
ts.each(&:join)
</code></pre>
<p>Here is what the output looks like after I've applied the patch:</p>
<pre><code>[aaron@TC ruby (trunk)]$ THREADS=1 SIZE=4096 time ./ruby test.rb
22.62 real 21.78 user 0.66 sys
[aaron@TC ruby (trunk)]$ THREADS=4 SIZE=4096 time ./ruby test.rb
15.87 real 34.53 user 8.27 sys
[aaron@TC ruby (trunk)]$
</code></pre>
<p>The digests that I'm calculating are for fairly large strings, so this patch works well for me. The downsides are that it seems slightly slower (though I'm not sure that it's significant) with a single thread:</p>
<p>Test code:</p>
<pre><code>require 'benchmark/ips'
require 'digest/sha1'
Benchmark.ips do |x|
x.report('sha1') { Digest::SHA1.hexdigest('x' * 4096) }
end
</code></pre>
<p>Before my patch (higher numbers are better):</p>
<pre><code>[aaron@TC ruby (trunk)]$ ./ruby shaips.rb
Calculating -------------------------------------
sha1 2.604k i/100ms
-------------------------------------------------
sha1 27.441k (± 3.9%) i/s - 138.012k
</code></pre>
<p>After my patch:</p>
<pre><code>[aaron@TC ruby (trunk)]$ ./ruby shaips.rb
Calculating -------------------------------------
sha1 2.419k i/100ms
-------------------------------------------------
sha1 25.848k (± 2.8%) i/s - 130.626k
</code></pre>
<p>Other downside is that I changed the <code>update</code> method to dup strings so that the GVL can be safely released.</p>
<p>This patch pays off for me because of the size of the strings I'm working with, but I'm not sure if it's fine for the general case.</p> Ruby master - Feature #11028 (Assigned): standalone running single file ( zipped archives of ruby...https://bugs.ruby-lang.org/issues/110282015-04-03T03:44:09Zzaxebo1 (zaxebo zaxebo)zaxebo1@gmail.com
<p>standalone running single file ( zipped archives of ruby code) running <strong>without installation</strong> using "gem install ..."<br>
prior examples in other languages:</p>
<pre><code>python myprg.pyz
java -jar myprg.jar
</code></pre>
<a name="Detailed-Description"></a>
<h2 >Detailed Description:<a href="#Detailed-Description" class="wiki-anchor">¶</a></h2>
<p>In python, if i have multiple program files: "<code>a1.py</code>, <code>a2.py</code>, <code>__main__.py</code>,<br>
<code>dir1/b1.py</code>, <code>dir1/b2.py</code>" and then i zip it as myprogram1.pyz<br>
then i can run it as "python myprogram.pyz" (<code>__main__.py</code> inside the zip<br>
file will be executed first). It is easy to distribute a single file<br>
myprogram1.pyz</p>
<p>see: <a href="http://blogs.gnome.org/jamesh/2012/05/21/python-zip-files/" class="external">http://blogs.gnome.org/jamesh/2012/05/21/python-zip-files/</a></p>
<hr>
<p>in java also we can bundle all the .class files into a single .jar file<br>
and run it</p>
<pre><code>java -jar myprogram1.jar
</code></pre>
<hr>
<p>Currently in ruby the ".gem" file requires installation using "gem install ...". Then it gives some program file for running.<br>
What i am asking is that some gem file should have manifest with which they can run directly without installing</p>
<p>That is, i request you to kind provide a feature in ruby that if i have lots of files like: <code>a1.rb</code>, <code>a2.rb</code>, <code>__main__.rb</code>, <code>dir1/a4.rb</code> etc.<br>
(say, which uses Ruby-GTK for a Desktop application). Then i should be able to bundle them as zip file, say myprog1.zip or myprog1.pz ( rbz=ruby's zipped executable archive).<br>
And then i can distribute this "single file" and execute it as:</p>
<pre><code>ruby myprog1.rbz
</code></pre>
<p>This will execute the <code>__main__.rb</code> file among all the other .rb files,<br>
inside this .zip archive myprog1.rbz .<br>
Note: this .rbz file extension can be .gemz or whatever, but this functionality of "standalone running zipped archives of ruby code running without installation" is essential</p> Ruby master - Feature #10782 (Assigned): Patch: Add constants for BigDecimal for ZERO, ONE, TENhttps://bugs.ruby-lang.org/issues/107822015-01-25T16:24:59Zgarysweaver (Gary Weaver)garysweaver@gmail.com
<p>We found with use of BigDecimal that we were often needing to compare BigDecimal with zero or initialize BigDecimal as 0 for a default value. This introduces a bit move overhead than is typically needed, since a simple BigDecimal.new('0') will suffice without any additional arguments. This BigDecimal instance does not change, so it makes sense to make it a constant.</p>
<p>In Java, they found that constants for zero, one, and ten were useful (see <a href="http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#ZERO" class="external">http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#ZERO</a>), so I thought it would be good to submit a patch for Ruby 2.3.0, just to see whether others would find this useful. I understand that we don't want to have constants for every possible value, and that it might be helpful if these had the same object id across ruby implementations similar to lower integer values having the same object id, however I don't think it is necessary or useful to compare object_id's for BigDecimal value comparison- the point is only not to have to retain and create new instances of BigDecimal for ZERO, ONE, or TEN.</p> Ruby master - Misc #10560 (Assigned): confusion between x=x+y, x+=y, x.concat(y) and y.each{|z| x...https://bugs.ruby-lang.org/issues/105602014-12-01T15:53:01Zmpapis (Michal Papis)mpapis@gmail.com
<p>while discussing a ticket I have noticed that there is no documentation for <code>+=</code></p>
<p>I was expecting <code>+=</code> to behave as <code>concat</code> but instead it behaves as <code>x=x+y</code> which for every operation clones the array and updates the variable with new value so it behaves similarly to <code>x=x.dup.concat(y)</code> and is slightly faster, but using plane <code>x.concat(y)</code> is a lot faster from both <code>each<<</code> and <code>+=</code></p>
<p>I would either like to get:</p>
<ul>
<li>updated docs that describe concept of <code>+=</code> and show the difference from <code>concat</code>
</li>
<li>or change <code>+=</code> to use <code>concat</code> which is faster - and add docs ;) (I would expect <code>+=</code> to use <code>concat</code> when available)</li>
</ul>
<p>here is a test:</p>
<pre><code>require 'benchmark'
rep = 10_000
Benchmark.bmbm do |x|
{
1..25 => [],
"a".."z" => "",
}.each do |base, storage|
base = base.to_a
basej = base
class_name = storage.class.to_s
x.report(class_name+'#concat') do
a = storage.dup
basej = base.join if storage == ""
rep.times { a.concat(basej) }
end
x.report(class_name+'#<<') do
a = storage.dup
basej = base.join if storage == ""
rep.times { base.each { |e| a << e } }
end
x.report(class_name+'#+=') do
a = storage.dup
basej = base.join if storage == ""
rep.times { a += basej }
end
x.report(class_name+'#dup.concat') do
a = storage.dup
basej = base.join if storage == ""
rep.times { a = a.dup.concat(basej) }
end
end
end
</code></pre>
<p>and here are results on my machine:</p>
<pre><code> user system total real
Array#concat 0.000000 0.000000 0.000000 ( 0.001422)
Array#<< 0.020000 0.000000 0.020000 ( 0.014356)
Array#+= 1.270000 0.230000 1.500000 ( 1.498558)
Array#dup.concat 2.720000 0.190000 2.910000 ( 2.915701)
String#concat 0.000000 0.000000 0.000000 ( 0.001072)
String#<< 0.030000 0.000000 0.030000 ( 0.025828)
String#+= 0.130000 0.010000 0.140000 ( 0.135143)
String#dup.concat 0.210000 0.020000 0.230000 ( 0.227470)
</code></pre> Ruby master - Feature #10038 (Assigned): Extend ObjectSpace.dump to expose buffer addresses for S...https://bugs.ruby-lang.org/issues/100382014-07-15T07:15:45Zko1 (Koichi Sasada)
<p>ObjectSpace.dump() expose internal information in JSON.<br>
How about to expose buffer addresses for String and Array?</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">Index: ext/objspace/objspace_dump.c
===================================================================
</span><span class="gd">--- ext/objspace/objspace_dump.c (revision 46821)
</span><span class="gi">+++ ext/objspace/objspace_dump.c (working copy)
</span><span class="p">@@ -178,12 +178,16 @@</span> dump_object(VALUE obj, struct dump_confi
dump_append(dc, ", \"broken\":true");
if (FL_TEST(obj, RSTRING_FSTR))
dump_append(dc, ", \"fstring\":true");
<span class="gd">- if (STR_SHARED_P(obj))
</span><span class="gi">+
+ if (STR_SHARED_P(obj)) {
</span> dump_append(dc, ", \"shared\":true");
<span class="gi">+ }
</span> else {
dump_append(dc, ", \"bytesize\":%ld", RSTRING_LEN(obj));
<span class="gd">- if (!STR_EMBED_P(obj) && !STR_SHARED_P(obj) && (long)rb_str_capacity(obj) != RSTRING_LEN(obj))
</span><span class="gi">+ if (!STR_EMBED_P(obj) && !STR_SHARED_P(obj) && (long)rb_str_capacity(obj) != RSTRING_LEN(obj)) {
</span> dump_append(dc, ", \"capacity\":%ld", rb_str_capacity(obj));
<span class="gi">+ dump_append(dc, ", \"ptr\":\"%p\"", RSTRING_PTR(obj));
+ }
</span>
if (is_ascii_string(obj)) {
dump_append(dc, ", \"value\":");
<span class="p">@@ -205,8 +209,14 @@</span> dump_object(VALUE obj, struct dump_confi
dump_append(dc, ", \"length\":%ld", RARRAY_LEN(obj));
if (RARRAY_LEN(obj) > 0 && FL_TEST(obj, ELTS_SHARED))
dump_append(dc, ", \"shared\":true");
<span class="gd">- if (RARRAY_LEN(obj) > 0 && FL_TEST(obj, RARRAY_EMBED_FLAG))
</span><span class="gi">+ if (RARRAY_LEN(obj) > 0) {
+ if (FL_TEST(obj, RARRAY_EMBED_FLAG)) {
</span> dump_append(dc, ", \"embedded\":true");
<span class="gi">+ }
+ else {
+ dump_append(dc, ", \"ptr\":\"%p\"", RARRAY_PTR(obj));
+ }
+ }
</span> break;
case T_CLASS:
</code></pre>
<p>With this hack, we can know the real memory address of them and cooperate with other native tools.</p>
<p>BTW, ObjectSpace.dump() should support T_SYMBOL.</p> Ruby master - Feature #9830 (Assigned): Support for GOST private/public keyshttps://bugs.ruby-lang.org/issues/98302014-05-11T20:34:05ZEnvek (Andrey Novikov)envek@envek.name
<p>Hello everyone.</p>
<p>We're required to use GOST encryption algorithms for signing requests, interacting with HTTPS services with client certificate authentication and so on.</p>
<p>OpenSSL 1.0.0 is bundled with GOST engine, and, if correctly configured, can handle all of these tasks from command line. Also see <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Ruby doesn't respect system OpenSSL configuration (Closed)" href="https://bugs.ruby-lang.org/issues/9822">#9822</a>.</p>
<p><strong>Issue</strong></p>
<p>Ruby can't read GOST private and public keys:</p>
<pre><code>ruby> privkey = OpenSSL::PKey.read(File.read('gost_r_34_10_2001_private_key.pem'))
OpenSSL::PKey::PKeyError: unsupported key type
ruby> # Same for public keys
ruby> crt = OpenSSL::X509::Certificate.new(File.read('gost_r_34_10_2001_certificate.pem'))
ruby> crt.public_key
OpenSSL::PKey::PKeyError: unsupported key type
</code></pre>
<p>The problem is there is no "Generic PKey" class in Ruby's OpenSSL.</p>
<p>In source in <code>ext/openssl/openssl_pkey.c</code> at line 76 in method <code>ossl_pkey_new</code> there is examination of key type and creating appropriate Ruby classes. But GOST R 34.10-2001 key type have type <code>NID_id_GostR3410_2001</code> (811), and Ruby fails.</p>
<p><strong>Possible solution</strong></p>
<p>GOST keys are EC keys in fact (at least for GOST R 34.10-2001). And, if I add <code>case NID_id_GostR3410_2001:</code> right before <code>case EVP_PKEY_EC:</code> and remove checks about key type in <code>ext/openssl/openssl_pkey_ec.c</code> – everything will work.</p>
<p>To illustrate this, I've attached required patches (one from issue <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Ruby doesn't respect system OpenSSL configuration (Closed)" href="https://bugs.ruby-lang.org/issues/9822">#9822</a>), self-signed GOST R 34.10-2001 certificate with private key and two test scripts.</p>
<p><strong>NOTE</strong>: You will need OpenSSL version 1.0.0 or newer with correct configuration, see links below!</p>
<p><strong>Question</strong></p>
<p>How should GOST keys support implemented in Ruby? Should it even use <code>OpenSSL::PKey::EC</code>, or, may be, subclass from it?</p>
<p>I'm not experienced neither in C programming nor in cryptography, but I would be glad to help with the implementation of this.</p>
<p><strong>Further information</strong></p>
<ul>
<li>
<strong>README.gost</strong>: Instructions for setting up OpenSSL and usage: <a href="https://github.com/openssl/openssl/blob/master/engines/ccgost/README.gost" class="external">https://github.com/openssl/openssl/blob/master/engines/ccgost/README.gost</a>
</li>
<li>
<strong>OpenSSL GOST engine source</strong>: <a href="https://github.com/openssl/openssl/tree/master/engines/ccgost" class="external">https://github.com/openssl/openssl/tree/master/engines/ccgost</a>
</li>
<li>
<strong>RFC 5830</strong>: GOST 28147-89: Encryption, Decryption, and Message Authentication Code (MAC) Algorithms:<br>
<a href="http://tools.ietf.org/html/rfc5830" class="external">http://tools.ietf.org/html/rfc5830</a>
</li>
<li>
<strong>RFC 5831</strong>: GOST R 34.11-94: Hash Function Algorithm:<br>
<a href="http://tools.ietf.org/html/rfc5831" class="external">http://tools.ietf.org/html/rfc5831</a>
</li>
<li>
<strong>RFC 5832</strong>: GOST R 34.10-2001: Digital Signature Algorithm:<br>
<a href="http://tools.ietf.org/html/rfc5832" class="external">http://tools.ietf.org/html/rfc5832</a>
</li>
<li>
<strong>RFC 4491</strong>: Using the GOST Algorithms with the Internet X.509 Public Key Infrastructure:<br>
<a href="http://tools.ietf.org/html/rfc4491" class="external">http://tools.ietf.org/html/rfc4491</a>
</li>
<li>
<strong>RFC 4490</strong>: Using the GOST Algorithms with Cryptographic Message Syntax (CMS):<br>
<a href="http://tools.ietf.org/html/rfc4490" class="external">http://tools.ietf.org/html/rfc4490</a>
</li>
<li>
<strong>RFC 4357</strong>: Additional Cryptographic Algorithms for Use with GOST Algorithms</li>
<li>Some stackoverflow.com related questions: <a href="http://stackoverflow.com/questions/12868384/openssl-gost-parameter-set" class="external">http://stackoverflow.com/questions/12868384/openssl-gost-parameter-set</a> and <a href="http://stackoverflow.com/questions/14580340/generate-gost-34-10-2001-keypair-and-save-it-to-some-keystore" class="external">http://stackoverflow.com/questions/14580340/generate-gost-34-10-2001-keypair-and-save-it-to-some-keystore</a>
</li>
</ul> Ruby master - Feature #9816 (Assigned): 文字列内の数字を数値として比較するメソッドhttps://bugs.ruby-lang.org/issues/98162014-05-08T09:37:26Znaruse (Yui NARUSE)naruse@airemix.jp
<p>文字列内の数字を数値として比較するメソッドを追加しませんか</p>
<p>そのような比較は一般的な用途としてはGUIシェルのファイラーが比較に用いており、<br>
Windows では StrCmpLogicalW が、OS X では NSString:compare:options:へのNSNumericSearch定数が提供されています。<br>
<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb759947(v=vs.85).aspx" class="external">http://msdn.microsoft.com/en-us/library/windows/desktop/bb759947(v=vs.85).aspx</a><br>
<a href="https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/c/econst/NSNumericSearch" class="external">https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/c/econst/NSNumericSearch</a></p>
<p>上記のような処理自体はさほど難しいものではありませんが、Rubyレベルで実装すると大量のオブジェクトを作ってしまいます。<br>
例えば <code>Gem::Version.new("2.1.10".freeze)<=>Gem::Version.new("2.1.9".freeze)</code> は47個、<br>
<code>"2.1.10".freeze.split('.').map(&:to_i)<=>"2.1.9".freeze.split('.').map(&:to_i)</code> だと16個のオブジェクトを作ります。<br>
<code>"2.1.10".freeze.numericcmp"2.1.9".freeze</code> ならば、もちろんオブジェクトは一つも作りません。</p>
<p>なお、上記の例でも示唆していますが、本メソッドは Ruby のバージョン表記の TEENY が2桁になった場合の比較に用いることができます。</p>
<p>パッチは以下の通りです。<br>
なお、メソッド名は String#numericcmp としています。<br>
(String#casecmpを念頭に置いた)</p>
<pre><code>diff --git a/string.c b/string.c
index c589c80..66f667f 100644
--- a/string.c
+++ b/string.c
@@ -2569,6 +2569,131 @@ rb_str_casecmp(VALUE str1, VALUE str2)
return INT2FIX(-1);
}
+VALUE
+numerical_compare(const char **pp1, const char *p1end, const char **pp2, const char *p2end)
+{
+ const char *s1 = *pp1, *p1, *s2 = *pp2, *p2;
+ ptrdiff_t len1, len2;
+ int r;
+
+ while (s1 < p1end && *s1 == '0') s1++;
+ p1 = s1;
+ while (p1 < p1end && ISDIGIT(*p1)) p1++;
+ len1 = p1 - s1;
+
+ while (s2 < p2end && *s2 == '0') s2++;
+ p2 = s2;
+ while (p2 < p2end && ISDIGIT(*p2)) p2++;
+ len2 = p2 - s2;
+
+ if (len1 != len2) {
+ return INT2FIX(len1 < len2 ? -1 : 1);
+ }
+
+ r = memcmp(s1, s2, len1);
+ if (r) return r < 0 ? INT2FIX(-1) : INT2FIX(1);
+
+ len1 = s1 - *pp1;
+ len2 = s2 - *pp2;
+ if (len1 != len2) {
+ return INT2FIX(len1 < len2 ? -1 : 1);
+ }
+
+ *pp1 = p1;
+ *pp2 = p2;
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * str.numericcmp(other_str) -> -1, 0, +1 or nil
+ *
+ * Variant of <code>String#<=></code>, which considers digits in strings
+ * are numeric value..
+ *
+ * "a1".numericcmp("a1") #=> 0
+ * "aa".numericcmp("a1") #=> 1
+ * "a1".numericcmp("aa") #=> -1
+ * "a1".numericcmp("a01") #=> -1
+ * "2.1.2".numericcmp("2.1.10") #=> 1
+ */
+
+static VALUE
+rb_str_numericcmp(VALUE str1, VALUE str2)
+{
+ long len;
+ rb_encoding *enc;
+ const char *p1, *p1end, *p2, *p2end;
+
+ StringValue(str2);
+ enc = rb_enc_compatible(str1, str2);
+ if (!enc) {
+ return Qnil;
+ }
+
+ p1 = RSTRING_PTR(str1); p1end = RSTRING_END(str1);
+ p2 = RSTRING_PTR(str2); p2end = RSTRING_END(str2);
+ if (single_byte_optimizable(str1) && single_byte_optimizable(str2)) {
+ while (p1 < p1end && p2 < p2end) {
+ if (ISDIGIT(*p1)) {
+ if (ISDIGIT(*p2)) {
+ VALUE r = numerical_compare(&p1, p1end, &p2, p2end);
+ if (!NIL_P(r)) return r;
+ }
+ else {
+ return INT2FIX(-1);
+ }
+ }
+ else if (ISDIGIT(*p2)) {
+ return INT2FIX(1);
+ }
+ if (*p1 != *p2) return INT2FIX(*p1 < *p2 ? -1 : 1);
+ p1++;
+ p2++;
+ }
+ }
+ else {
+ while (p1 < p1end && p2 < p2end) {
+ int l1, c1 = rb_enc_ascget(p1, p1end, &l1, enc);
+ int l2, c2 = rb_enc_ascget(p2, p2end, &l2, enc);
+
+ if (0 <= c1 && 0 <= c2) {
+ if (ISDIGIT(*p1)) {
+ if (ISDIGIT(*p2)) {
+ VALUE r = numerical_compare(&p1, p1end, &p2, p2end);
+ if (!NIL_P(r)) return r;
+ }
+ else {
+ return INT2FIX(-1);
+ }
+ }
+ else if (ISDIGIT(*p2)) {
+ return INT2FIX(1);
+ }
+ if (*p1 != *p2) return INT2FIX(*p1 < *p2 ? -1 : 1);
+ p1++;
+ p2++;
+ }
+ else {
+ int r;
+ l1 = rb_enc_mbclen(p1, p1end, enc);
+ l2 = rb_enc_mbclen(p2, p2end, enc);
+ len = l1 < l2 ? l1 : l2;
+ r = memcmp(p1, p2, len);
+ if (r != 0)
+ return INT2FIX(r < 0 ? -1 : 1);
+ if (l1 != l2)
+ return INT2FIX(l1 < l2 ? -1 : 1);
+ }
+ p1 += l1;
+ p2 += l2;
+ }
+ }
+ if (RSTRING_LEN(str1) == RSTRING_LEN(str2)) return INT2FIX(0);
+ if (RSTRING_LEN(str1) > RSTRING_LEN(str2)) return INT2FIX(1);
+ return INT2FIX(-1);
+}
+
static long
rb_str_index(VALUE str, VALUE sub, long offset)
{
@@ -8721,6 +8846,7 @@ Init_String(void)
rb_define_method(rb_cString, "eql?", rb_str_eql, 1);
rb_define_method(rb_cString, "hash", rb_str_hash_m, 0);
rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1);
+ rb_define_method(rb_cString, "numericcmp", rb_str_numericcmp, 1);
rb_define_method(rb_cString, "+", rb_str_plus, 1);
rb_define_method(rb_cString, "*", rb_str_times, 1);
rb_define_method(rb_cString, "%", rb_str_format_m, 1);
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index 8366424..f9c788b 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -2104,6 +2104,29 @@ class TestString < Test::Unit::TestCase
assert_equal(1, "\u3042B".casecmp("\u3042a"))
end
+ def test_numericcmp
+ assert_equal(-1, "2.1.0".numericcmp("2.1.1"))
+ assert_equal(-1, "2.1.9".numericcmp("2.1.10"))
+ assert_equal( 0, "a1".numericcmp("a1"))
+ assert_equal( 1, "aa".numericcmp("a1"))
+ assert_equal(-1, "a1".numericcmp("aa"))
+ assert_equal(-1, "a1".numericcmp("a01"))
+ assert_equal(-1, "a0001".numericcmp("a00001"))
+ assert_equal( 0, "a1a".numericcmp("a1a"))
+ assert_equal( 1, "a1b".numericcmp("a1a"))
+ assert_equal(-1, "a9a".numericcmp("a10a"))
+ assert_equal( 1, "b".numericcmp("a"))
+ assert_equal( 0, "\u30421".numericcmp("\u30421"))
+ assert_equal( 1, "\u3042\u3042".numericcmp("\u30421"))
+ assert_equal(-1, "\u30421".numericcmp("\u3042\u3042"))
+ assert_equal(-1, "\u30421".numericcmp("\u304201"))
+ assert_equal(-1, "\u30420001".numericcmp("\u304200001"))
+ assert_equal( 0, "\u30421\u3042".numericcmp("\u30421\u3042"))
+ assert_equal( 1, "\u30421\u3044".numericcmp("\u30421\u3042"))
+ assert_equal(-1, "\u30429\u3042".numericcmp("\u304210\u3042"))
+ assert_equal( 1, "\u3044".numericcmp("\u3042"))
+ end
+
def test_upcase2
assert_equal("\u3042AB", "\u3042aB".upcase)
end
</code></pre> Ruby master - Feature #9235 (Assigned): Documentation for commercial supporthttps://bugs.ruby-lang.org/issues/92352013-12-10T05:36:24Zzzak (zzak _)
<p>We should document the following:</p>
<ul>
<li>What happens when a Ruby version goes EOL?</li>
<li>What can (my) company do to help maintain an EOL ruby?</li>
<li>How do we backport security patches?</li>
<li>How do we run tests?</li>
<li>How do we release our own version of ruby?</li>
</ul> Ruby master - Bug #9189 (Assigned): Build failure on Windows in case of nonascii TEMP environment.https://bugs.ruby-lang.org/issues/91892013-12-01T18:06:20Zphasis68 (Heesob Park)phasis@gmail.com
<p>I experienced a build failure during build extension library with trunk on Windows.</p>
<pre><code>make[2]: Entering directory `/c/work/ruby-2.1.0-r43936/ext/bigdecimal'
generating bigdecimal-i386-mingw32.def
compiling bigdecimal.c
In file included from bigdecimal.c:20:0:
bigdecimal.h:62:1: error: static declaration of 'labs' follows non-static declar
ation
make[2]: *** [bigdecimal.o] Error 1
make[2]: Leaving directory `/c/work/ruby-2.1.0-r43936/ext/bigdecimal'
make[1]: *** [ext/bigdecimal/all] Error 2
make[1]: Leaving directory `/c/work/ruby-2.1.0-r43936'
make: *** [build-ext] Error 2
</code></pre>
<p>I found the cause of this error is mkmk failure.<br>
Here is a part of mkmf.log</p>
<pre><code>have_func: checking for labs() in stdlib.h... -------------------- no
"i686-w64-mingw32-gcc -o conftest.exe -I../../.ext/include/i386-mingw32 -I../.././include -I../.././ext/bigdecimal -D_WIN32_WINNT=0x0501 -D_FILE_OFFSET_BITS=64 -O3 -fno-omit-frame-pointer -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration conftest.c -L. -L../.. -L. -lmsvcrt-ruby210-static -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi "
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Cannot create temporary file in C:\Users\??苑?AppData\Local\Temp\: Invalid argument
</code></pre>
<p>The TEMP environment varable is</p>
<pre><code>C:\work\ruby-2.1.0-r43936>set TEMP
TEMP=C:\Users\희섭\AppData\Local\Temp
</code></pre>
<p>It seems that miniruby cannot handle encoding properly.</p>
<pre><code>C:\work\ruby-2.1.0-r43936>miniruby -ve "p ENV['TEMP']"
ruby 2.1.0dev (2013-11-30 trunk 43936) [i386-mingw32]
"C:\\Users\\\xED\x9D\xAC\xEC\x84\xAD\\AppData\\Local\\Temp"
C:\work\ruby-2.1.0-r43936>miniruby.exe -ve "p ENV['TEMP'].encoding"
ruby 2.1.0dev (2013-11-30 trunk 43936) [i386-mingw32]
#<Encoding:ASCII-8BIT>
</code></pre>
<p>Whereas, the final ruby can handle encoding properly.</p>
<pre><code>C:\work>ruby -ve "p ENV['TEMP']"
ruby 2.1.0dev (2013-11-30 trunk 43923) [i386-mingw32]
"C:\\Users\\희섭\\AppData\\Local\\Temp"
C:\work>ruby -ve "p ENV['TEMP'].encoding"
ruby 2.1.0dev (2013-11-30 trunk 43923) [i386-mingw32]
#<Encoding:CP949>
</code></pre> Ruby master - Misc #9136 (Assigned): Deprecated Enumerator.new(object, method) bad for BasicObjecthttps://bugs.ruby-lang.org/issues/91362013-11-21T22:18:28Zatlas (Atlas Prime)a7145@live.com
<p>=begin<br>
Documentation it says:</p>
<p>In the second, deprecated, form, a generated Enumerator iterates over the given object using the given method with the given arguments passed.</p>
<p>Use of this form is discouraged. Use Kernel#enum_for or Kernel#to_enum instead.</p>
<pre><code> e = Enumerator.new(ObjectSpace, :each_object)
#-> ObjectSpace.enum_for(:each_object)
</code></pre>
<p>But (({#enum_for})) and (({#to_enum})) are not available to subclasses of (({BasicObject})). In fact, I was defining (({#to_enum})) for a class that is a subclass of (({BasicObject})), and now I get warning of deprecation.<br>
=end</p> Ruby master - Bug #9115 (Assigned): Logger traps all exceptions; breaks Timeouthttps://bugs.ruby-lang.org/issues/91152013-11-16T12:30:25Zcphoenix (Chris Phoenix)cphoenix@gmail.com
<p>Line 577-579 of logger.rb</p>
<pre><code> rescue Exception => ignored
warn("log writing failed. #{ignored}")
end
</code></pre>
<p>Thus, when the system times out in the middle of writing a log message, it warns "log writing failed. execution expired" and just keeps right on running.</p>
<p>This is true in 1.9.3 as well. I haven't looked at older versions.</p>
<p>Pardon me while I go grep "rescue Exception" in the entire Ruby codebase, and see whether I can reliably use Timeout at all...</p>
<p>OK, you might check out C:\Ruby200\lib\ruby\gems\2.0.0\gems\activerecord-3.2.13\lib\active_record\railties\databases.rake</p>
<p>All the other "rescue Exception" seem to re-raise it, except maybe C:\Ruby200\lib\ruby\2.0.0\xmlrpc\server.rb and C:\Ruby200\lib\ruby\gems\2.0.0\gems\activesupport-3.2.13\lib\active_support\callbacks.rb</p> Ruby master - Feature #9020 (Assigned): Net::HTTPResponse predicate/query methodshttps://bugs.ruby-lang.org/issues/90202013-10-14T20:43:15Ztimcraft (Tim Craft)
<a name="SUMMARY"></a>
<h1 >SUMMARY<a href="#SUMMARY" class="wiki-anchor">¶</a></h1>
<p>I would like to propose adding predicate/query methods to Net::HTTPResponse for testing the status/type of response. For example:</p>
<pre><code>response.ok?
response.not_found?
response.client_error?
response.server_error?
</code></pre>
<a name="BACKGROUND"></a>
<h1 >BACKGROUND<a href="#BACKGROUND" class="wiki-anchor">¶</a></h1>
<p>The approach I've most commonly used/encountered for testing the status of a response is to compare with an integer, for example:</p>
<pre><code>response.code.to_i == 200
</code></pre>
<p>Subjectively I could say this kind of code is awkward/tedious to type, and not very "intention revealing". More practically/objectively it's a potential source of error. By mistyping the "magic number" it's possible for this expression to "silently fail" and test the wrong status. That would be an easy thing to spot in these examples, but much more difficult to track down within a typical codebase.</p>
<p>Another approach would be to test the type/class of the response object, for example:</p>
<pre><code>Net::HTTPOK === response
</code></pre>
<p>Subjectively I would say this doesn't feel very Ruby-ish. More practically/objectively it tightly couples the caller to the implementation details of Net::HTTP, making it difficult to stub or swap in a different library.</p>
<a name="PROPOSAL"></a>
<h1 >PROPOSAL<a href="#PROPOSAL" class="wiki-anchor">¶</a></h1>
<p>I would like to propose adding predicate/query methods to Net::HTTPResponse in order to encapsulate the implementation details of testing for different statuses and to provide a more abstract interface to the caller. For example:</p>
<pre><code>response.ok?
response.not_found?
</code></pre>
<p>This is more concise/readable. In most cases it would be easier and "less fiddly" to type out than the existing approaches presented above.</p>
<p>Compared to testing with integers it is one method call instead of three (I'm considering that as better from a readability perspective, not a performance perspective), and it eliminates the "failing silently" issue.</p>
<p>Compared to testing the type/class of the response object it doesn't couple the caller to implementation details of Net::HTTP, so it would be easier to stub or swap-in another library that provides the same interface.</p>
<p>Overall it feels much simpler and much more Ruby-ish.</p>
<p>In addition I would propose adding a few extra methods to test for ranges of statuses, for example:</p>
<pre><code>response.client_error?
response.server_error?
</code></pre>
<p>Similar benefits/rationale.</p>
<a name="IMPLEMENTATION"></a>
<h1 >IMPLEMENTATION<a href="#IMPLEMENTATION" class="wiki-anchor">¶</a></h1>
<p>I have already been using methods like this in some gems, and I have created a "proof of concept" implementation which monkey-patches Net::HTTP to test the idea out. Available here:</p>
<pre><code>http://rubygems.org/gems/net-http-predicates
https://github.com/timcraft/net-http-predicates
</code></pre>
<p>I can think of various different ways to implement a patch, so if this feature would be accepted into ruby-trunk I would welcome suggestions/guidance on a preferred implementation.</p>
<p>These changes would be backwards compatible and straightforward to provide as a backport, either in the backports library/gem or as a standalone gem.</p>
<a name="DISCUSSION"></a>
<h1 >DISCUSSION<a href="#DISCUSSION" class="wiki-anchor">¶</a></h1>
<p>Before discussing how to implement this patch I would like to get people's thoughts on the idea/proposal, and some indication of whether this could be accepted into ruby-trunk (or not). If it would be accepted I'm happy to write/submit the patch itself.</p> Ruby master - Bug #9010 (Assigned): ./configure --prefix= cannot handle directories with spaceshttps://bugs.ruby-lang.org/issues/90102013-10-10T07:50:41Zpostmodern (Hal Brodigan)postmodern.mod3@gmail.com
<p>It appears that the linking task fails when the --prefix value contains spaces.</p>
<p>Steps to Reproduce:</p>
<ol>
<li>./configure --prefix="$HOME/foo bar"</li>
<li>make</li>
</ol>
<p>Expected Result: success<br>
Actual Result:</p>
<p>make[2]: Entering directory <code>/home/hal/src/ruby-2.0.0-p247' linking ruby gcc: error: bar/lib: No such file or directory gcc: error: bar/lib: No such file or directory make[2]: *** [ruby] Error 1 make[2]: Leaving directory </code>/home/hal/src/ruby-2.0.0-p247'<br>
make[1]: *** [all] Error 2<br>
make[1]: Leaving directory `/home/hal/src/ruby-2.0.0-p247'<br>
make: *** [build-ext] Error 2</p> Ruby master - Feature #8959 (Assigned): Allow top level prependhttps://bugs.ruby-lang.org/issues/89592013-09-27T06:24:27Zkyrylo (Kyrylo Silin)silin@kyrylo.org
<p>Since <code>include</code> works on top level, it's reasonable to enable top level<br>
<code>prepend</code> as well.</p>
<p>I've already added a patch (it was partially merged by nobu): <a href="https://github.com/ruby/ruby/pull/395" class="external">https://github.com/ruby/ruby/pull/395</a></p> Ruby master - Feature #8460 (Assigned): PATCH: optparse: add `keep_unknown` optionhttps://bugs.ruby-lang.org/issues/84602013-05-29T20:39:13Zfelipec (Felipe Contreras)felipe.contreras@gmail.com
<p>Currently people have to do very convoluted tricks, essentially making<br>
it impossible for optparse to keep unknown options.</p>
<p>The safest and cleanest way is to do it in the code itself.</p>
<p>[1] <a href="http://www.ruby-forum.com/topic/88081" class="external">http://www.ruby-forum.com/topic/88081</a><br>
[2] <a href="http://stackoverflow.com/questions/3642331/can-optparse-skip-unknown-options-to-be-processed-later-in-a-ruby-program" class="external">http://stackoverflow.com/questions/3642331/can-optparse-skip-unknown-options-to-be-processed-later-in-a-ruby-program</a></p> Ruby master - Feature #8295 (Assigned): Float や Rational から(可能であれば)正確な BigDecimal を生成する機能https://bugs.ruby-lang.org/issues/82952013-04-19T17:26:29Zmetanest (Makoto Kishimoto)
<p>=begin<br>
たまに、Float を正確に表現する BigDecimal が欲しいことがあります。</p>
<p>(有効数字の考え方からは邪道ですが。また普通は printf の "%a" による<br>
十六進表現で用が足りることも多いでしょう)</p>
<p>十進でも桁数を必要なだけ伸ばせば、普通の 2 進の浮動小数点数なら正確に<br>
表現できます。また、Rational も分母が 2 と 5 以外の約数を持たない場合に<br>
限っては、正確に BigDecimal に変換できます。</p>
<p>そういった場合に、BigDecimal(0.1, nil) のように精度に nil を指定すれば、<br>
正確な変換が行われたら便利だと思います。Rationalについては、任意の n 進法<br>
を指定して正確な文字列表現にできる場合には変換するという機能(たとえば、<br>
Rational(1, 3) は、3 進法で 0.1 です)というのもありうるかと思いますが、<br>
そこまで実装してはいません。</p>
<p>基本的なアイディアを実装したコードは<br>
((<a href="URL:https://gist.github.com/metanest/5418814" class="external">URL:https://gist.github.com/metanest/5418814</a>))<br>
にあります。名前などのインタフェースには検討の必要が残っていると思います。<br>
=end</p> Ruby master - Feature #8271 (Assigned): Proposal for moving to a more visible, formal process for...https://bugs.ruby-lang.org/issues/82712013-04-16T05:35:58Zheadius (Charles Nutter)headius@headius.com
<p>Proposal for moving to a more visible, formal process for feature requests.</p>
<ol>
<li>Introduction</li>
</ol>
<p>In order to make it clear that an issue or change to MRI is a visible feature change all implementations will need to consider implementing, I propose that we move all feature requests into a separate Redmine project. I see the following benefits to this arrangement:</p>
<ul>
<li>Features are always in one place. One-stop-shopping for implementers to track changes to "Ruby" that are not specific to MRI.</li>
<li>No confusion about where feature requests should be filed. Currently, people usually file feature requests against "trunk", but sometimes against version-specific projects. It's also valid to say that a feature improvement or clarification is not specific to trunk. Tracking features separate from "trunk" and version-specific Redmine projects keeps the process localized to one Redmine project.</li>
<li>Ability to add fields to "feature" issues that do not have relevance for "bugs". For example, bugs do not usually need approval from matz, but features could have an "approved by matz" field. We could also have other metadata tracking other implementations, such as "approved by implementations" or "affects implementations" with drop-downs for known impls. One-stop-shopping to know whether a given impl is affected and/or has agreed to add the feature.</li>
<li>More visible process for folks in the community that can't follow the current process or don't believe there's a process in place.</li>
</ul>
<p>I propose that the project be called CommonRuby (already created and under some use) and be a top-level entry on bugs.ruby-lang.org.</p>
<ol start="2">
<li>Processes</li>
</ol>
<p>For issues that are obviously new features (i.e. user knows to select "feature" in the current tracker), issues would be filed directly in CommonRuby. Discussion proceeds exactly as the current process, perhaps with additional issue fields added that allow tracking matz approval, etc, as stated in §1.</p>
<p>Issues that are approved for a Ruby version will have fields/metadata to indicate at which version the feature is available. This may mean specifying multiple releases if, for example, 2.0.1 and 1.9.3p400 would both see a feature added (just saying 1.9.3p400 is insufficient since the feature does not exist in 2.0.0. This avoids having to track features through the backport process to know if there are multiple releases that contain the feature.</p>
<p>For issues that start out as bugs, but later become features or feature changes, those issues would be tranferred into CommonRuby at the point where it's obvious they're feature-related.</p>
<ol start="3">
<li>Detriments</li>
</ol>
<p>Benefits are stated in the introduction above.</p>
<p>Possible detriments with mitigation:</p>
<ul>
<li>Confusion by users about where to file features.</li>
</ul>
<p>This would be mitigated by adding more information to bug-related home pages about the CommonRuby project. The "feature" value in current "trunk" project could either be removed (after migrating features to CommonRuby) or modified to error/warn or switch the issue to CommonRuby programmatically.</p>
<ul>
<li>More complex process.</li>
</ul>
<p>I believe this process is no more complicated than the current process. It also makes the process of evolving "common Ruby" more isolated from MRI development and may make it easier for users to track that evolution.</p>
<ol start="4">
<li>Further justification</li>
</ol>
<p>A lot of noise has been made over the past several months about Ruby lacking a process for new and changing features. The design process proposed by Brian Shirai (née Ford) gained some measure of popularity, but requires a complete retooling and reworking of current processes, making it infeasible for short-term implementation. Other process-change proposals have been kicked around on ruby-core, but the truth is that there <em>is</em> a current process, even if it's not particularly visible. By implementing my proposal, the process would become more obvious and transparent without major impact to MRI's development or Ruby's evolutionary processes.</p>
<ol start="5">
<li>Prior art</li>
</ol>
<p>The PEP (Python Enhancement Proposal) and JSR (Java Specification Request) processes are partial inspiration for this proposal. The latter governs all visible feature changes to Python independent of bug reports to the main "CPython" implementation. The latter governs (through a heavy and overly-strict process) changes to "Java" independent of individual JVM implementations. Both processes have been very successful at isolating spec changes from implementation changes, although the JSR process tends to move very slowly and be less transparent than it should be.</p>
<ol start="6">
<li>Conclusion</li>
</ol>
<p>Ruby does not lack a process for adding or changing features, but it does lack visibility into that process and in many cases fails to provide tools to non-MRI implementations to participate. Moving feature requests and discussion to a CommonRuby project independent of MRI will make the process more transparent and easier to follow (for users and implementers) while having minimal impact on the current process.</p> Ruby master - Feature #8164 (Assigned): Public/Privatehttps://bugs.ruby-lang.org/issues/81642013-03-26T07:48:13ZAnonymous
<ul>
<li>#private<a href="http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-private" class="external">http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-private</a>
<ul>
<li>#private_class_method<a href="http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-private_class_method" class="external">http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-private_class_method</a>
</li>
<li>#public<a href="http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-public" class="external">http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-public</a>
</li>
<li>#public_class_method<a href="http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-public_class_method" class="external">http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-public_class_method</a>
</li>
</ul>
</li>
</ul>
<p>Would it be a good idea to compress these 4 methods to 2 methods?</p>
<p>public - Can set both instance <em>and</em> class methods to public by passing<br>
them in as symbol<br>
private - Can set both instance <em>and</em> class methods to private by passing<br>
them in as symbol</p>
<p>and enable them to be called at top of class? Is this a good idea? It would<br>
clean up Module# and encourage use of these two<br>
as methods rather than keywords</p> Ruby master - Feature #8126 (Assigned): OpenSSL::SSL::SSLSocket does not define #recv and #send m...https://bugs.ruby-lang.org/issues/81262013-03-20T06:38:27Zpostmodern (Hal Brodigan)postmodern.mod3@gmail.com
<p>OpenSSL::SSL::SSLSocket does not define #recv/#send methods and is not compatible with TCPSocket.</p> Ruby master - Bug #7964 (Assigned): Writing an ASCII-8BIT String to a StringIO created from a UTF...https://bugs.ruby-lang.org/issues/79642013-02-26T16:32:50Zbrixen (Brian Shirai)brixen@gmail.com
<p>=begin<br>
In the following script, an ASCII-8BIT String is written to a StringIO created with a UTF-8 String without error. However, a << b or a + b will raise an exception, as will writing an ASCII-8BIT String to a File with UTF-8 external encoding.</p>
<ul>
<li>
<p>$ cat file_enc.rb</p>
<a name="encoding-utf-8"></a>
<h1 >encoding: utf-8<a href="#encoding-utf-8" class="wiki-anchor">¶</a></h1>
<p>require 'stringio'</p>
<p>a = "On a very cold morning, it was -8°F."<br>
b = a.dup.force_encoding "ascii-8bit"</p>
<p>io = StringIO.new a<br>
io.write(b)<br>
p io.string.encoding</p>
<p>File.open "data.txt", "w:utf-8" do |f|<br>
f.write a<br>
f.write b<br>
end</p>
</li>
<li>
<p>$ ruby2.0 -v file_enc.rb<br>
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin10.8.0]<br>
#<a href="Encoding:UTF-8" class="external">Encoding:UTF-8</a><br>
file_enc.rb:13:in <code>write': "\xC2" from ASCII-8BIT to UTF-8 (Encoding::UndefinedConversionError) from file_enc.rb:13:in </code>block in '<br>
from file_enc.rb:11:in <code>open' from file_enc.rb:11:in </code>'</p>
</li>
<li>
<p>$ ruby1.9.3 -v file_enc.rb<br>
ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-darwin10.8.0]<br>
#<a href="Encoding:UTF-8" class="external">Encoding:UTF-8</a><br>
file_enc.rb:13:in <code>write': "\xC2" from ASCII-8BIT to UTF-8 (Encoding::UndefinedConversionError) from file_enc.rb:13:in </code>block in '<br>
from file_enc.rb:11:in <code>open' from file_enc.rb:11:in </code>'<br>
=end</p>
</li>
</ul> Ruby master - Feature #7580 (Assigned): Range translationhttps://bugs.ruby-lang.org/issues/75802012-12-17T14:43:24ZAnonymous
<p>=begin<br>
I would like to propose the (({#+})) and (({#-})) methods on (({Range})).</p>
<p>These would be useful for translating ranges - for example, given a range where the endpoints are 1-indexed, the range could be translated by 1 in the negative direction to use in (({Array#[]})).</p>
<p>Instead of doing a syntactically-bulky manual translation like so:</p>
<p>ary[(range.begin - 1)..(range.end - 1)]</p>
<p>(({Range#-})) could be used instead:</p>
<p>ary[range - 1]</p>
<p>The translation methods would not handle certain endpoint types specially, they would just pass the call on.</p>
<p>Here's an example implementation in Ruby:</p>
<p>class Range<br>
def +(other)<br>
Range.new(self.begin + other, self.end + other, exclude_end?)<br>
end</p>
<pre><code>def -(other)
Range.new(self.begin - other, self.end - other, exclude_end?)
end
</code></pre>
<p>end</p>
<p>=end</p> Ruby master - Feature #7532 (Assigned): Hardcoded compiler locationhttps://bugs.ruby-lang.org/issues/75322012-12-07T17:57:20Zmpapis (Michal Papis)mpapis@gmail.com
<p>Currently RbConfig::CONFIG["CC"] is hardcoded during compilation, this is an issue when compiling ruby that can be run on other machines, ruby used for compilation might be not available on target system.</p>
<p>A good example is Apple OSX, there are multiple ways to get gcc-4.2 for it - considering <a href="https://bugs.ruby-lang.org/issues/5883" class="external">https://bugs.ruby-lang.org/issues/5883</a> GNU GCC is preferred over LLVM clang.</p>
<p>So assuming ruby is compiled on machine A with /usr/bin/gcc4.2 - and moved to machine B with /opt/local/bin/gcc - which both are the same version "i686-apple-darwin11-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)" - just compiled in different paths. Compiling gems with native extensions would fail in that case because of the recorded compiler path.</p>
<p>Please consider changing the line in rbconfig.rb to: CONFIG["CC"] = ENV["CC"] || "..."</p>
<p>It will allow changing compiler after moving ruby. As '--enable-load-relative' is a prerequisite for moving rubies it could be also used as a switch for adding that change as I can understand there might be a need for preserving compiler used for building ruby so the same is used for building gems.</p>
<p>This trick is used by default in MagLev <a href="http://maglev.github.com/" class="external">http://maglev.github.com/</a></p> Ruby master - Feature #7518 (Assigned): Fiddle::Pointer#to_str and Fiddle::Pointer#to_int should ...https://bugs.ruby-lang.org/issues/75182012-12-05T23:38:35Zngoto (Naohisa Goto)ngotogenome@gmail.com
<p>There are Fiddle::Pointer#to_str and to_int, to be used for implicit conversion to String and Integer, respectively. I think those implicit conversion methods should be removed.<br>
(Note that there are to_s and to_i, explicit conversion to String and Integer, respectively.)</p>
<p>About to_str: Because Fiddle::Pointer is not always a pointer of char *, and careless conversion of invalid pointer to a string would frequently cause SEGV. So, I think implicit conversion to string is very danger and it should be removed.</p>
<p>About to_int: Unlike to_str, pointer arithmetic methods are available in Fiddle::Pointer, but it lacks many methods for treating it as integer, and I think Fiddle::Pointer is not suitable for implicit conversion to integer.</p> Ruby master - Feature #7488 (Assigned): Receiving object_id in object creation probeshttps://bugs.ruby-lang.org/issues/74882012-12-01T23:24:08ZauthorNari (Narihiro Nakamura)authorNari@gmail.com
<p>Hi.</p>
<p>I want to get a object id in object creation probes to know a creation<br>
point of a suspect object.</p>
<p>I've wrote a patch for above.<br>
<a href="https://gist.github.com/4182140" class="external">https://gist.github.com/4182140</a></p>
<p>Could you check it?</p>
<a name="Im-sorry-I-dont-have-a-Mac-so-I-do-not-execute-dtraces-tests"></a>
<h1 >I'm sorry, I don't have a Mac so I do not execute dtrace's tests...<a href="#Im-sorry-I-dont-have-a-Mac-so-I-do-not-execute-dtraces-tests" class="wiki-anchor">¶</a></h1>
<p>Thanks!</p> Ruby master - Feature #7394 (Assigned): Enumerable#find ifnone parameter could be non-callablehttps://bugs.ruby-lang.org/issues/73942012-11-19T12:36:44Zzzak (zzak _)
<p>from github:<br>
<a href="https://github.com/ruby/ruby/pull/186" class="external">https://github.com/ruby/ruby/pull/186</a></p>
<p>In trunk the <code>Enumerable#find</code> method <code>ifnone</code> parameter has to be callable or <code>nil</code>. I found that sometimes I want to return a simple value without wrapping it in a proc. This pull request adds support for non-callable defaults when no items match.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span> <span class="o">=</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>
</code></pre>
<p>The current behavior</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="nb">proc</span> <span class="p">{</span> <span class="ss">:foo</span> <span class="p">})</span> <span class="p">{</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span> <span class="o">></span> <span class="mi">3</span> <span class="p">}</span> <span class="c1">#=> :foo</span>
</code></pre>
<p>With patch</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span> <span class="o">></span> <span class="mi">3</span> <span class="p">}</span> <span class="c1">#=> 0</span>
</code></pre> Ruby master - Feature #7349 (Assigned): Struct#inspect needs more meaningful outputhttps://bugs.ruby-lang.org/issues/73492012-11-14T11:32:05Zpostmodern (Hal Brodigan)postmodern.mod3@gmail.com
<p>When inheriting directly from Struct.new, Class#ancestors shows a meaningless anonymous Class:</p>
<pre><code>class Point < Struct.new(:x, :y)
def distance
((x ** 2) + (y ** 2)) ** 0.5
end
end
Point.ancestors
# => [Point, #<Class:0x007fe204a1a228>, Struct, Enumerable, Object, Kernel, BasicObject]
</code></pre>
<p>Perhaps, the anonymous Class could list the Struct's fields?</p>
<pre><code>#<Class:x, y>
</code></pre> Ruby master - Feature #7321 (Assigned): Newton.#nsolve の第 2 引数が複数の役割を持つhttps://bugs.ruby-lang.org/issues/73212012-11-10T16:17:17Zsho-h (Sho Hashimoto)sho-h@netlab.jp
<p>Newton.#nsolve の第 2 引数 x は以下の 2 つの役割を持つようです。</p>
<ul>
<li>探索を開始する点</li>
<li>解を代入</li>
</ul>
<p>newton.rb のコメントにも同じ内容が記述してあるのでわかるといえばわかるのですが、できればそれぞれ分けた方がわかりやすいのではないかと思いました。Newton.#nsolve の戻り値として返すか、引数を追加するのはどうでしょう。</p> Ruby master - Feature #6973 (Assigned): Add an #integral? method to Numeric to test for whole-num...https://bugs.ruby-lang.org/issues/69732012-09-04T06:03:43Zregularfry (Alex Young)alex@blackkettle.org
<p>Numeric#integer? checks whether an instance is an Integer. It is often useful to check whether the value of a non-Integer variable is actually a whole number, and the #integer? method doesn't help here.</p>
<p>This patch adds Numeric#integral?, which performs this check.</p> Ruby master - Feature #6857 (Assigned): bigdecimal/math BigMath.E/BigMath.exp R. P. Feynman inspi...https://bugs.ruby-lang.org/issues/68572012-08-11T23:46:18Zroyaltm (Rafał Michalski)
<p>The algorythms to calculate E and exp programmed in BigMath module are the very straightforward interpretation of the series 1 + x + x^2/2! +<br>
x^3/3! + ....<br>
Therefore they are slow.</p>
<p>Try it yourself:</p>
<pre><code> require 'bigdecimal/math'
def timer; s=Time.now; yield; puts Time.now-s; end
timer { BigMath.E(1000) } #-> 0.038848
timer { BigMath.E(10000) } #-> 16.526972
timer { BigMath.E(100000) } #-> lost patience
</code></pre>
<p>That's because every iteration divides 1 by n! and the dividend grows extremely fast.</p>
<p>In "Surely You're Joking, Mr. Feynman!" (great book, you should read it if you didn't already) R. P. Feynman said:</p>
<p>"One day at Princeton I was sitting in the lounge and overheard some mathematicians talking about the series for e^x, which is 1 + x + x^2/2! +<br>
x^3/3! Each term you get by multiplying the preceding term by x and dividing by the next number. For example, to get the next term after x^4/4! you<br>
multiply that term by x and divide by 5. It's very simple."</p>
<p>Yes it's very simple indeed. Why it's not been applied in such a great, modern and popular language? Is it because people just forget about simple solutions today?</p>
<p>Here is a Feynman's optimized version of BigMath.E:</p>
<pre><code> def E(prec)
raise ArgumentError, "Zero or negative precision for E" if prec <= 0
n = prec + BigDecimal.double_fig
y = d = i = one = BigDecimal('1')
while d.nonzero? && (m = n - (y.exponent - d.exponent).abs) > 0
m = BigDecimal.double_fig if m < BigDecimal.double_fig
d = d.div(i, m)
i += one
y += d
end
y
end
</code></pre>
<p>Now, let's put it to the test:</p>
<pre><code> (1..1000).all? {|n| BigMath.E(n).round(n) == E(n).round(n) }
=> true
BigMath.E(10000).round(10000) == E(10000).round(10000)
=> true
</code></pre>
<p>What about the speed then?</p>
<pre><code> timer { E(1_000) } #-> 0.003832 ~ 10 times faster
timer { E(10_000) } #-> 0.139862 ~ 100 times faster
timer { E(100_000) } #-> 8.787411 ~ dunno?
timer { E(1_000_000) } #-> ~11 minutes
</code></pre>
<p>The same simple rule might be applied to BigDecimal.exp() which originally uses the same straightforward interpretation of power series.<br>
Feynman's pure ruby version of BigMath.exp (the ext version seems now pointless anyway):</p>
<pre><code> def exp(x, prec)
raise ArgumentError, "Zero or negative precision for exp" if prec <= 0
x = case x
when Float
BigDecimal(x, prec && prec <= Float::DIG ? prec : Float::DIG + 1)
else
BigDecimal(x, prec)
end
one = BigDecimal('1', prec)
case x.sign
when BigDecimal::SIGN_NaN
return BigDecimal::NaN
when BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal::SIGN_NEGATIVE_ZERO
return one
when BigDecimal::SIGN_NEGATIVE_FINITE
x = -x
inv = true
when BigDecimal::SIGN_POSITIVE_INFINITE
return BigDecimal::INFINITY
when BigDecimal::SIGN_NEGATIVE_INFINITE
return BigDecimal.new('0')
end
n = prec + BigDecimal.double_fig
if x.round(prec) == one
y = E(prec)
else
y = d = i = one
while d.nonzero? && (m = n - (y.exponent - d.exponent).abs) > 0
m = BigDecimal.double_fig if m < BigDecimal.double_fig
d = d.mult(x, m).div(i, m)
i += one
y += d
end
end
y = one.div(y, n) if inv
y.round(prec - y.exponent)
end
(1..1000).all? {|n| exp(E(n),n) == BigMath.exp(BigMath.E(n),n) }
# => true
(1..1000).all? {|n| exp(-E(n),n) == BigMath.exp(-BigMath.E(n),n) }
# => true
(-10000..10000).all? {|n| exp(BigDecimal(n)/1000,100) == BigMath.exp(BigDecimal(n)/1000,100) }
# => true
(1..1000).all? {|n| exp(BigMath.PI(n),n) == BigMath.exp(BigMath.PI(n),n) }
# => true
timer { BigMath.exp(BigDecimal('1').div(3, 10), 100) } #-> 0.000496
timer { exp(BigDecimal('1').div(3, 10), 100) } #-> 0.000406 faster but not that really
timer { BigMath.exp(BigDecimal('1').div(3, 10), 1_000) } #-> 0.029231
timer { exp(BigDecimal('1').div(3, 10), 1_000) } #-> 0.004554 here we go...
timer { BigMath.exp(BigDecimal('1').div(3, 10), 10_000) } #-> 12.554197
timer { exp(BigDecimal('1').div(3, 10), 10_000) } #-> 0.189462 oops :)
timer { exp(BigDecimal('1').div(3, 10), 100_000) } #-> 11.914613 who has the patience to compare?
</code></pre>
<p>Arguments with large mantissa should slow down the results of course:</p>
<pre><code> timer { BigMath.exp(BigDecimal('1').div(3, 1_000), 1_000) } #-> 0.119048
timer { exp(BigDecimal('1').div(3, 1_000), 1_000) } #-> 0.066177
timer { BigMath.exp(BigDecimal('1').div(3, 10_000), 10_000) } #-> 68.083222
timer { exp(BigDecimal('1').div(3, 10_000), 10_000) } #-> 29.439336
</code></pre>
<p>Though still two times faster than the ext version.</p>
<p>It seems Dick Feynman was not such a joker after all. I think he was a master in treating lightly "serious" things and treating very seriously things that didn't matter to anybody else.</p>
<p>I'd write a patch for ext version if you are with me. Just let me know.</p> Ruby master - Feature #6841 (Assigned): Shorthand for Assigning Return Value of Method to Selfhttps://bugs.ruby-lang.org/issues/68412012-08-07T11:37:53Zwardrop (Tom Wardrop)tom@tomwardrop.com
<p>=begin<br>
Quite often in Ruby, I find myself doing something like: (({my_var[:foo][:bar] = my_var[:foo][:bar].to_i})) or (({obj.foo.bar = obj.foo.bar.to_i})). Realising this, I thought of what would be a fairly nice shorthand syntax for this, which could be: (({my_var[:foo][:bar] .= to_i})). How this works should be pretty self-explanatory. The (({.=})) operator works exactly like any other assignment operator of this nature.</p>
<p>Would be nice to see this in Ruby 2.0. Wondering what others think of this?<br>
=end</p> Ruby master - Feature #6802 (Assigned): String#scan should have equivalent yielding MatchDatahttps://bugs.ruby-lang.org/issues/68022012-07-27T16:17:42Zprijutme4ty (Ilya Vorontsov)prijutme4ty@gmail.com
<p>Ruby should have method to obtain not an array of arrays but of MatchData objects. It can help in obtaining named groups:</p>
<p>pattern = /x: (?\d+) y:(?\d+)/<br>
polygon = []<br>
text.scan_for_pattern(pattern){|m| polygon << Point.new(m[:x], m[:y]) }</p>
<p>Not to break existing code we need unique name. Ideas? May be #each_match</p> Ruby master - Feature #6769 (Assigned): rbinstall.rb: install both src and batch files separetelyhttps://bugs.ruby-lang.org/issues/67692012-07-22T10:04:13Zluislavena (Luis Lavena)luislavena@gmail.com
<p>=begin<br>
Hello,</p>
<p>Current behavior of rbinstall.rb is to concat bin scripts (erb, rake, rdoc, etc) along with a batchfile stub in a single file, resulting in erb.bat, rdoc.bat etc.</p>
<p>Those files works OK when invoked directly, but they do not support the following scenarios:</p>
<ul>
<li>
<p>Invoke it like "ruby -S rake", which looks for extension-less script in the path (and that does not exist)</p>
</li>
<li>
<p>Cannot invoke those scripts from another script, example, from Rake, do "ruby 'rdoc'" will not work.</p>
</li>
</ul>
<p>To circumvent this issue at RubyInstaller, we copied the original bin scripts and replaced the batchfile stubs with simple ones:</p>
<p><a href="https://github.com/oneclick/rubyinstaller/blob/master/recipes/interpreter/ruby19.rake#L188-197" class="external">https://github.com/oneclick/rubyinstaller/blob/master/recipes/interpreter/ruby19.rake#L188-197</a></p>
<p>===</p>
<p>I would like to change rbinstall.rb to copy over verbatim bin scripts and simple batchfiles stubs.</p>
<p>That will solve the above two issues I mentioned plus open the scenario to a easy executable-based launcher, similar to gem-exefy:</p>
<p><a href="https://github.com/bosko/gem-exefy" class="external">https://github.com/bosko/gem-exefy</a></p>
<p>To have identifiable scripts in list of process plus, customized firewall rules and remove the dreaded "Terminate batch job" prompt.</p>
<p>Before I start working on this, I wanted to know what do you think about this?</p>
<p>Thanks in advance for your feedback and looking forward your responses.<br>
=end</p> Ruby master - Feature #6682 (Assigned): Add a method to return an instance attached by a singleto...https://bugs.ruby-lang.org/issues/66822012-07-01T19:22:05Zryoqun (Ryo Onodera)ryoqun@gmail.com
<p>=begin<br>
Currently, there is no easy way to get the attached instance from a singleton class. For MRI, we have to resort to writing an C extension. So it'll be useful to add an instance method to Class to return the attached instance if the given class object is a singleton class.</p>
<p>I'll show what I want in the code-wise with the following code snippet:</p>
<p>text = "I love Ruby."<br>
klass = text.singleton_class</p>
<a name="gt-ltClassString0x000000027383e8gt"></a>
<h1 >=> #<Class:#<a href="String:0x000000027383e8" class="external">String:0x000000027383e8</a>><a href="#gt-ltClassString0x000000027383e8gt" class="wiki-anchor">¶</a></h1>
<p>klass.singleton_instance # <= This is the new method.</p>
<a name="gt-I-love-Ruby"></a>
<h1 >=> "I love Ruby."<a href="#gt-I-love-Ruby" class="wiki-anchor">¶</a></h1>
<p>String.singleton_instance # <= This should return nil because String isn't a singleton class and there is no singleton instance, rather there will be many instances.</p>
<a name="gt-nil"></a>
<h1 >=> nil<a href="#gt-nil" class="wiki-anchor">¶</a></h1>
<p>As for use cases, in my case, I wanted to create a module to add class methods. And it has some state, so must be initialized properly. And it can equally be used by Class#extend and Class#include like this:</p>
<p>module Countable<br>
attr_reader(:count)</p>
<pre><code>class << self
def extended(extended_class)
p("extending #{extended_class}")
super
initialize_state(extended_class)
end
def included(included_class)
p("including #{included_class}")
super
if included_class.singleton_instance # <= Currently, I can't do this.
initialize_state(included_class.singleton_instance)
end
end
private
def initialize_state(object)
p("initializing state of #{object}")
object.instance_variable_set(:@count, 0)
end
end
</code></pre>
<p>end</p>
<p>class Person<br>
extend(Countable)<br>
end</p>
<p>class Book<br>
class << self<br>
include(Countable)<br>
end<br>
end</p>
<p>p(Person.count)<br>
p(Book.count)</p>
<a name="gt-extending-Person"></a>
<h1 >=> "extending Person"<a href="#gt-extending-Person" class="wiki-anchor">¶</a></h1>
<a name="gt-initializing-state-of-Person"></a>
<h1 >=> "initializing state of Person"<a href="#gt-initializing-state-of-Person" class="wiki-anchor">¶</a></h1>
<a name="gt-including-ClassBook"></a>
<h1 >=> "including #<a href="Class:Book" class="external">Class:Book</a>"<a href="#gt-including-ClassBook" class="wiki-anchor">¶</a></h1>
<a name="gt-initializing-state-of-Book"></a>
<h1 >=> "initializing state of Book"<a href="#gt-initializing-state-of-Book" class="wiki-anchor">¶</a></h1>
<a name="gt-0"></a>
<h1 >=> 0<a href="#gt-0" class="wiki-anchor">¶</a></h1>
<a name="gt-0-2"></a>
<h1 >=> 0<a href="#gt-0-2" class="wiki-anchor">¶</a></h1>
<p>Others wanted this functionality as shown by ((<this stackoverflow page|URL:<a href="http://stackoverflow.com/questions/7053455/given-a-ruby-metaclass-how-do-i-get-the-instance-to-which-it-is-attached%3E" class="external">http://stackoverflow.com/questions/7053455/given-a-ruby-metaclass-how-do-i-get-the-instance-to-which-it-is-attached></a>)). Also, I found several actual C-extensions for this kind of functionality on the wild browsing ((<a search result|URL:<a href="https://github.com/search?q=rb_iv_get+__attached__&repo=&langOverride=&start_value=1&type=Code&language=C%3E" class="external">https://github.com/search?q=rb_iv_get+__attached__&repo=&langOverride=&start_value=1&type=Code&language=C></a>)) on github.</p>
<ul>
<li>((<eigen|URL:<a href="https://github.com/elliottcable/refinery/blob/853dcc2254557200d1d6be4cb9c105e8fa9d01a9/ext/eigen/eigen.c#L12%3E" class="external">https://github.com/elliottcable/refinery/blob/853dcc2254557200d1d6be4cb9c105e8fa9d01a9/ext/eigen/eigen.c#L12></a>))</li>
<li>((<mult|URL:<a href="https://github.com/banister/mult/blob/6a1d0bdd383e7e231c5b7c2c718204dfb6ba28ca/ext/mult/mult.c#L43%3E" class="external">https://github.com/banister/mult/blob/6a1d0bdd383e7e231c5b7c2c718204dfb6ba28ca/ext/mult/mult.c#L43></a>))</li>
</ul>
<p>Thanks for creating a great language. Especially I love its meta-programming capability. I'd wish this feature to lead to better meta-programming capability of Ruby.<br>
=end</p> Ruby master - Feature #6648 (Assigned): Provide a standard API for retrieving all command-line fl...https://bugs.ruby-lang.org/issues/66482012-06-26T07:56:37Zheadius (Charles Nutter)headius@headius.com
<p>=begin<br>
Currently there are no standard mechanisms to get the flags passed to the currently running Ruby implementation. The available mechanisms are not ideal:</p>
<ul>
<li>Scanning globals and hoping they have not been tweaked to new settings</li>
<li>Using external wrappers to launch Ruby</li>
<li>???</li>
</ul>
<p>Inability to get the full set of command-line flags, including flags passed to the VM itself (and probably VM-specific) makes it impossible to launch subprocess Ruby instances with the same settings.</p>
<p>A real world example of this is "((%bundle exec%))" when called with a command line that sets various flags, a la ((%jruby -Xsome.vm.setting --1.9 -S bundle exec%)). None of these flags can propagate to the subprocess, so odd behaviors result. The only option is to put the flags into an env var (((|JRUBY_OPTS|)) or ((|RUBYOPT|))) but this breaks the flow of calling a simple command line.</p>
<p>JRuby provides mechanisms to get all its command line options, but they require calling Java APIs from Ruby's API set. Rubinius provides its own API for accessing comand-line options, but I do not know if it includes VM-level flags as well as standard Ruby flags.</p>
<p>I know there is a (({RubyVM})) namespace in the 2.0 line. If that namespace is intended to be general-purpose for VM-level features, it would be a good host for this API. Something like...</p>
<p>class << RubyVM<br>
def vm_args; end # returns array of command line args <em>not</em> passed to the target script</p>
<pre><code>def script; end # returns the script being executed...though this overlaps with $0
def script_args; end # returns args passed to the script...though this overlaps with ARGV, but that is perhaps warranted since ARGV can be modified (i.e. you probably want the original args)
</code></pre>
<p>end<br>
=end</p> Ruby master - Feature #6613 (Assigned): VT_RECORD, IRecordInfo Support in WIN32OLEhttps://bugs.ruby-lang.org/issues/66132012-06-21T07:54:17Zdsisnero (Dominic Sisneros)dsisnero@gmail.com
<p>WIN32OLE has no support for VT_RECORD VARIANTS. Python and Perl use the<br>
functions GetRecordInfoFromTypeInfo and GetRecordInfoFromGuids to add<br>
support for VT_RECORD and the IRecordInfo interface.</p>
<p>suggest having a class IRecordInfo and support for generating a Class<br>
for the UDT to use this Record/Struct in ruby</p>
<p>The method starting on 1395 needs a case statement for VT_RECORD and a way to turn that into a IRECORD class</p>
<p>static void *<br>
get_ptr_of_variant(VARIANT *pvar)<br>
{<br>
switch(V_VT(pvar)) {<br>
case VT_UI1:<br>
return &V_UI1(pvar);<br>
break;</p>
<p>The IDL definitions for the methods are as follows</p>
<p>HRESULT GetRecordInfoFromTypeInfo(<br>
__in ITypeInfo *pTypeInfo,<br>
__out IRecordInfo **ppRecInfo<br>
);</p>
<p>HRESULT GetRecordInfoFromGuids(<br>
__in REFGUID rGuidTypeLib,<br>
__in ULONG uVerMajor,<br>
__in ULONG uVerMinor,<br>
__in LCID lcid,<br>
__in REFGUID rGuidTypeInfo,<br>
__out IRecordInfo **ppRecInfo<br>
);</p>
<p>here is the CTYPES definition for python that adds this support</p>
<p>class IRecordInfo(IUnknown):<br>
# C:/vc98/include/OAIDL.H 5974<br>
<em>iid</em> = GUID("{0000002F-0000-0000-C000-000000000046}")</p>
<pre><code>def GetFieldNames(self, *args):
count = c_ulong()
self.__com_GetFieldNames(count, None)
array = (BSTR * count.value)()
self.__com_GetFieldNames(count, array)
result = array[:]
# XXX Should SysFreeString the array contents. How to?
return result
</code></pre>
<p>IRecordInfo. <em>methods</em> = [<br>
COMMETHOD([], HRESULT, 'RecordInit',<br>
(['in'], c_void_p, 'pvNew')),<br>
COMMETHOD([], HRESULT, 'RecordClear',<br>
(['in'], c_void_p, 'pvExisting')),<br>
COMMETHOD([], HRESULT, 'RecordCopy',<br>
(['in'], c_void_p, 'pvExisting'),<br>
(['in'], c_void_p, 'pvNew')),<br>
COMMETHOD([], HRESULT, 'GetGuid',<br>
(['out'], POINTER(GUID), 'pguid')),<br>
COMMETHOD([], HRESULT, 'GetName',<br>
(['out'], POINTER(BSTR), 'pbstrName')),<br>
COMMETHOD([], HRESULT, 'GetSize',<br>
(['out'], POINTER(c_ulong), 'pcbSize')),<br>
COMMETHOD([], HRESULT, 'GetTypeInfo',<br>
(['out'], POINTER(POINTER(ITypeInfo)), 'ppTypeInfo')),<br>
COMMETHOD([], HRESULT, 'GetField',<br>
(['in'], c_void_p, 'pvData'),<br>
(['in'], c_wchar_p, 'szFieldName'),<br>
(['out'], POINTER(VARIANT), 'pvarField')),<br>
COMMETHOD([], HRESULT, 'GetFieldNoCopy',<br>
(['in'], c_void_p, 'pvData'),<br>
(['in'], c_wchar_p, 'szFieldName'),<br>
(['out'], POINTER(VARIANT), 'pvarField'),<br>
(['out'], POINTER(c_void_p), 'ppvDataCArray')),<br>
COMMETHOD([], HRESULT, 'PutField',<br>
(['in'], c_ulong, 'wFlags'),<br>
(['in'], c_void_p, 'pvData'),<br>
(['in'], c_wchar_p, 'szFieldName'),<br>
(['in'], POINTER(VARIANT), 'pvarField')),<br>
COMMETHOD([], HRESULT, 'PutFieldNoCopy',<br>
(['in'], c_ulong, 'wFlags'),<br>
(['in'], c_void_p, 'pvData'),<br>
(['in'], c_wchar_p, 'szFieldName'),<br>
(['in'], POINTER(VARIANT), 'pvarField')),<br>
COMMETHOD([], HRESULT, 'GetFieldNames',<br>
(['in', 'out'], POINTER(c_ulong), 'pcNames'),<br>
(['in'], POINTER(BSTR), 'rgBstrNames')),<br>
COMMETHOD([], BOOL, 'IsMatchingType',<br>
(['in'], POINTER(IRecordInfo))),<br>
COMMETHOD([], HRESULT, 'RecordCreate'),<br>
COMMETHOD([], HRESULT, 'RecordCreateCopy',<br>
(['in'], c_void_p, 'pvSource'),<br>
(['out'], POINTER(c_void_p), 'ppvDest')),<br>
COMMETHOD([], HRESULT, 'RecordDestroy',<br>
(['in'], c_void_p, 'pvRecord'))]</p>
<p>################################################################</p>
<a name="functions"></a>
<h1 >functions<a href="#functions" class="wiki-anchor">¶</a></h1>
<p>_oleaut32 = oledll.oleaut32</p>
<p>def GetRecordInfoFromTypeInfo(tinfo):<br>
"Return an IRecordInfo pointer to the UDT described in tinfo"<br>
ri = POINTER(IRecordInfo)()<br>
_oleaut32.GetRecordInfoFromTypeInfo(tinfo, byref(ri))<br>
return ri</p>
<p>def GetRecordInfoFromGuids(rGuidTypeLib, verMajor, verMinor, lcid,<br>
rGuidTypeInfo):<br>
ri = POINTER(IRecordInfo)()<br>
_oleaut32.GetRecordInfoFromGuids(byref(GUID(rGuidTypeLib)),<br>
verMajor, verMinor, lcid,<br>
byref(GUID(rGuidTypeInfo)),<br>
byref(ri))<br>
return ri</p> Ruby master - Feature #6596 (Assigned): New method `Array#indexes`https://bugs.ruby-lang.org/issues/65962012-06-15T18:05:05Zrobin850 (Robin Dupret)robin.dupret@gmail.com
<p>I submitted a pull request on Github that provides a new method <code>Array#indexes</code>. It departs from <code>Array#index</code> in such a way that it returns an array of indexes and not the single first occurrence that is relevant.</p>
<p>The reason I want this method is that I don't understand why <code>Array#index</code> returns a single index if the parameter is in the array several times.</p>
<p>Examples</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span> <span class="o">=</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="mi">1</span><span class="p">]</span>
<span class="n">a</span><span class="p">.</span><span class="nf">indexes</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c1">#=> [0, 3]</span>
<span class="n">a</span><span class="p">.</span><span class="nf">index</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># => 0</span>
</code></pre>
<p>In my opinion, it's not logical to return only a single index since <code>1</code> is in the array twice.</p> Ruby master - Feature #6445 (Assigned): request for default length/position on string indexhttps://bugs.ruby-lang.org/issues/64452012-05-17T13:02:30Zbotp (bot pena)botpena@gmail.com
<p>would be nice if ruby has default for "rest or up to end of string"</p>
<p>eg</p>
<p>"hello"[2,] => should default to "hello"[2..-1]<br>
or<br>
"hello"[2..] => should default to "hello"[2..-1]</p> Ruby master - Bug #6360 (Assigned): Debug information build even without requesting ithttps://bugs.ruby-lang.org/issues/63602012-04-26T08:46:44Zluislavena (Luis Lavena)luislavena@gmail.com
<p>Hello,</p>
<p>While working on latest RubyInstaller release for 1.9.3-p194 our team detected a bigger shared library and import library being generated.</p>
<p>After further inspection, we found this commit:<br>
<a href="https://github.com/ruby/ruby/commit/ffdaca1d748804f2b5ca2de612f17cf6c78d351b" class="external">https://github.com/ruby/ruby/commit/ffdaca1d748804f2b5ca2de612f17cf6c78d351b</a></p>
<p>Backported r34840 into ruby_1_9_3 branch</p>
<p>The above change added -ggdb to CFLAGS even when was not provided by debugflags configure option.</p>
<p>The following is the comparison of "make" summary with and without the change:</p>
<p>Current trunk:</p>
<pre>
C:\Users\Luis\Projects\oss\ruby\build32>make
CC = gcc
LD = ld
LDSHARED = gcc -shared
CFLAGS = -O3 -fno-omit-frame-pointer -ggdb -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Werror=pointer-arith -Werror=write-strings -Werror=declaration-after-statement -Werror=implicit-function-declaration
XCFLAGS = -include ruby/config.h -include ruby/missing.h -D_FORTIFY_SOURCE=2 -fno-strict-overflow -fvisibility=hidden -DRUBY_EXPORT
CPPFLAGS = -DFD_SETSIZE=32767 -D_WIN32_WINNT=0x0501 -I. -I.ext/include/i386-mingw32 -I../include -I..
DLDFLAGS = -Wl,--enable-auto-image-base,--enable-auto-import -Wl,--out-implib=libmsvcrt-ruby200.dll.a msvcrt-ruby200.def -Wl,--stack,0x00200000,--enable-auto-import
SOLIBS = msvcrt-ruby200.res.o -lshell32 -lws2_32 -limagehlp
</pre>
<p>Reverting r34840:</p>
<pre>
C:\Users\Luis\Projects\oss\ruby\build32>make
CC = gcc
LD = ld
LDSHARED = gcc -shared -s
CFLAGS = -O3 -fno-omit-frame-pointer -g -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Werror=pointer-arith -Werror=write-strings -Werror=declaration-after-statement -Werror=implicit-function-declaration
XCFLAGS = -include ruby/config.h -include ruby/missing.h -D_FORTIFY_SOURCE=2 -fno-strict-overflow -fvisibility=hidden -DRUBY_EXPORT
CPPFLAGS = -DFD_SETSIZE=32767 -D_WIN32_WINNT=0x0501 -I. -I.ext/include/i386-mingw32 -I../include -I..
DLDFLAGS = -Wl,--enable-auto-image-base,--enable-auto-import -Wl,--out-implib=libmsvcrt-ruby200.dll.a msvcrt-ruby200.def -Wl,--stack,0x00200000,--enable-auto-import
SOLIBS = msvcrt-ruby200.res.o -lshell32 -lws2_32 -limagehlp
</pre>
<p>Notice that -g changed into -ggdb instead.</p>
<p>I think debug symbols shouldn't be compiled unless requested and this is a regression.</p> Ruby master - Feature #6354 (Assigned): Remove escape (break/return/redo/next support) from class...https://bugs.ruby-lang.org/issues/63542012-04-25T12:12:17Zko1 (Koichi Sasada)
<p>Let's remove global escape (break/return/redo/next support) from class/module scope.</p>
<p>Yes, it introduces incompatibility. However, anyone use it?<br>
I think the following examples are evil (difficult to understand).</p>
<a name="examples"></a>
<h1 >examples:<a href="#examples" class="wiki-anchor">¶</a></h1>
<p>1.times{<br>
class C<br>
break # break from 1.times<br>
end<br>
}</p>
<p>1.times{<br>
class C<br>
module M<br>
break # break from 1.times<br>
end<br>
end<br>
}</p>
<p>3.times{|n|<br>
p n # repeat print 0<br>
class C<br>
redo<br>
end<br>
}</p>
<p>->{<br>
class C<br>
return return from outer lambda block<br>
end<br>
}.call</p>
<p>->{<br>
proc{<br>
class C<br>
return # return from outer lambda (not proc) block<br>
end<br>
}.call<br>
}.call</p>
<p>etc, etc.</p> Ruby master - Feature #6317 (Assigned): Range#cover?の引数としてRangeインスタンスを受けられるようにして欲しいhttps://bugs.ruby-lang.org/issues/63172012-04-18T20:51:08Zmasaakiaoyagi (Masaaki Aoyagi)masaaki.aoyagi@gmail.com
<p>青柳と申します。</p>
<p>以下のように、Range#cover?の引数としてRangeインスタンスを<br>
受けられるようにして欲しいです。<br>
(1..4).cover?(2..3) # => true<br>
(1..4).cover?(0..3) # => false</p>
<p>取り敢えず実装してみましたので、添付いたします。</p> Ruby master - Feature #6293 (Assigned): new queue / blocking queueshttps://bugs.ruby-lang.org/issues/62932012-04-14T08:28:58Ztenderlovemaking (Aaron Patterson)tenderlove@ruby-lang.org
<p>Hi,</p>
<p>I'd like to add new Queue objects to ruby. Whenever I use queues, I either use them in a blocking or non-blocking manner only, so I have separated them in to two classes Thread::Queue, and Thread::BlockingQueue.</p>
<p>Other notable differences, these queues:</p>
<ul>
<li>implement <code>poll</code>, which will return a nil if the queue is empty</li>
<li>do not allow <code>nil</code> to be in the queue as it would interfere with <code>poll</code>
</li>
<li>include Enumerable</li>
</ul>
<p>I think these will be a good basis for implementing a Deque, SynchronizedQueue, and PriorityQueue.</p>
<p>I've attached a patch against trunk.</p> Ruby master - Feature #6265 (Assigned): Remove 'useless' 'concatenation' syntaxhttps://bugs.ruby-lang.org/issues/62652012-04-06T21:53:53Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<p>What is wrong with this code:</p>
<p>some_method 'argument1', 'argument2' 'argument3'</p>
<p>Yes, the missing colon, but it is not always easy to notice that...</p>
<p>What is this ('concatenation' 'syntax') useful for?</p>
<p>Why writing ('some ' 'concatenation') instead of 'some concatenation'?</p>
<p>A missing colon between string arguments can lead to some bugs that may be hard to find, specially if the arguments are optional.</p>
<p>And I can't see any useful case where this allowed syntax for concatenation would help.</p> Ruby master - Feature #6133 (Assigned): SSLSocketをshutdownできないhttps://bugs.ruby-lang.org/issues/61332012-03-13T00:17:22Zkik (Masashi Kikuchi)kik314@gmail.com
<p><a href="http://www.openssl.org/docs/ssl/SSL_shutdown.html" class="external">http://www.openssl.org/docs/ssl/SSL_shutdown.html</a><br>
に対応するメソッドがないので、送信の終わりを送れません。ただし微妙にshutdown(2)とインターフェースが違ってます。</p> Ruby master - Feature #6012 (Assigned): Proc#source_location also return the columnhttps://bugs.ruby-lang.org/issues/60122012-02-14T09:17:30Zrogerdpack (Roger Pack)rogerpack2005@gmail.com
<p>As originally suggested in <a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/42418" class="external">http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/42418</a></p>
<p>Suggestion/feature request:<br>
have #source_location also return the beginning column where it was defined.<br>
["test.rb", 8, 33]</p>
<p>Thanks!<br>
-roger-</p> Ruby master - Feature #5825 (Assigned): Sweet instance var assignment in the object initializerhttps://bugs.ruby-lang.org/issues/58252011-12-30T22:49:03Zgoshakkk (Gosha Arinich)me@goshakkk.name
<p>I'm very excited about this feature in CoffeeScript, and think it might be a nice-to-have thing in Ruby 2.0.</p>
<p>That's how I think it would look like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Me</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="vi">@name</span><span class="p">,</span> <span class="vi">@age</span><span class="p">,</span> <span class="vi">@location</span><span class="p">);</span> <span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>So we can declare <code>@variable</code>s in the initializer method parameters definition to avoid assigning instance variables from method arguments by hand, like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Me</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="n">age</span><span class="p">,</span> <span class="n">location</span><span class="p">)</span>
<span class="vi">@name</span> <span class="o">=</span> <span class="nb">name</span>
<span class="vi">@age</span> <span class="o">=</span> <span class="n">age</span>
<span class="vi">@location</span> <span class="o">=</span> <span class="n">location</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>Want to hear what do you guys think, does that feature worth being included in 2.0?</p> Ruby master - Feature #5781 (Assigned): Query attributes (attribute methods ending in `?` mark)https://bugs.ruby-lang.org/issues/57812011-12-20T04:57:11Ztrans (Thomas Sawyer)
<p>Pretty sure this has come up before, but I'd like to revisit b/c I don't understand why it isn't allowed.</p>
<p>Sometimes I define "query" attributes, and in those cases I'd like the reader method to end in a <code>?</code> mark. Currently I have to do:</p>
<pre><code># @attribute
def foo?
@foo
end
</code></pre>
<p>or, if I don't mind a shadowing bare method,</p>
<pre><code>attr :foo
alias_method :foo?, :foo
</code></pre>
<p>So why not just allow:</p>
<pre><code>attr :foo?
</code></pre>
<p>Currently this causes an error. But why? It just seems like a waste of potentially cleaner code.</p> Ruby master - Feature #5764 (Assigned): Net::HTTP should assume HTTP/0.9 on unexpected responseshttps://bugs.ruby-lang.org/issues/57642011-12-15T06:01:34Zmstyer (Mike Styer)michael@styer.net
<p>Currently Net::HTTP.read_status_line throws Net::HTTPBadResponse if the status line does not conform to HTTP/1.1 specifications.</p>
<p>But in cases when the web server implements a request size limit, it may not read HTTP/1.1 trailer after the request URI and may send back an HTTP/0.9 response.</p>
<p>Nginx does this for 414 Request-URI Too Large responses:</p>
<p><a href="http://lxr.evanmiller.org/http/source/http/ngx_http_header_filter_module.c#L95" class="external">http://lxr.evanmiller.org/http/source/http/ngx_http_header_filter_module.c#L95</a><br>
<a href="http://forum.nginx.org/read.php?2,52862,52862" class="external">http://forum.nginx.org/read.php?2,52862,52862</a></p>
<p>Perl's Net::HTTP provides a "laxed" option to read_response_headers() to assume HTTP/0.9 if it can't find an HTTP/1.1 status line. Ruby should provide a similar option.</p> Ruby master - Feature #5749 (Assigned): new method String#match_all neededhttps://bugs.ruby-lang.org/issues/57492011-12-12T18:03:57Zyimutang (Joey Zhou)
<p>The String class should contain an instance method 'match_all', which is a mixture of 'match' and 'scan'.</p>
<p>The method 'scan' is not a very powerful tool, its result(the yielding thing) is just a matched string or an array of captured strings.</p>
<p>p 'a1bc2de3f'.scan(/(.)\d(.)/) # [["a", "b"], ["c", "d"], ["e", "f"]]</p>
<p>If the regex argument contains groups, I even cannot get the whole matched string, and no information about the matched offsets.</p>
<p>So, a 'match_all' is very necessary. It scan the string, finding every matched, and yielding <em>MatchData instance</em> to the following block.</p>
<p>Here's a simple implemention in Ruby:</p>
<p>class String<br>
def match_all(re,i=0)<br>
if block_given?<br>
while m = self.match(re,i)<br>
yield m<br>
i = m.end(0)<br>
end<br>
return self<br>
else<br>
ary = []<br>
while m = self.match(re,i)<br>
ary << m<br>
i = m.end(0)<br>
end<br>
return ary<br>
end<br>
end<br>
end</p>
<p>However, it is not efficient in the 'while m = self.match(re,i)' way, because it scan the string again and again. If string is UTF8-encoded and contains out-of-ASCII characters, I'm afraid getting the start index of it is so expensive.</p>
<p>So, I think a built-in 'match_all' method, which behaves just like 'scan' but yield MatchData, is needed.</p>
<p>Please consider it, thank you!</p> Ruby master - Feature #5741 (Assigned): Secure Erasure of Passwordshttps://bugs.ruby-lang.org/issues/57412011-12-11T06:02:13ZMartinBosslet (Martin Bosslet)Martin.Bosslet@gmail.com
<p>In other languages it is considered good practice to securely erase<br>
passwords immediately after they were used. Imagine authentication<br>
in a web app - ultimately a String containing the password arrives<br>
at the server, where it will be processed and compared to some<br>
previously stored value. After this is done, there is no need to<br>
store these password Strings any longer, so they should be<br>
discarded right away (more on why later).</p>
<p>In C, you would simply overwrite the array of bytes with zeroes or<br>
random values. In Java, Strings are immutable, that's why there it<br>
is common practice to use char[] for all things password and overwrite<br>
them when done.</p>
<p>Currently, there is no way in Ruby to overwrite the memory that<br>
was used by a String. String#clear and String#replace both use<br>
str_discard internally, which only frees the underlying pointer<br>
without overwriting it.</p>
<p>The problem with not erasing passwords is this: the contents of the<br>
String stay in memory until they are finally GC'ed. But even then<br>
only the pointer will be freed, leaving the contents mostly intact<br>
until the memory is reclaimed and overwritten later on.</p>
<p>This could be exploited if an attacker had access to the memory of<br>
the server. This could happen in many ways: a core dump after a<br>
crash, access to the host if the server runs in a VM, or even by<br>
deep-freezing the DRAM :) [1]</p>
<p>It could be argued that given the examples above, much more<br>
devastating attacks would be possible since in all of those<br>
cases you more or less have physical access to the machine. But<br>
I would still consider this to be a valid concern, if not only<br>
for the reason of never opening additional attack surfaces if<br>
they can be avoided relatively easily.</p>
<p>I also found [2], which seems to show that Python deals with<br>
similar problems and it also contains more background info.</p>
<p>Eric Hodel and I discussed this yesterday and Eric came up with<br>
a C extension that can be used to illustrate the problem (attached).</p>
<p>If you inspect the resulting core dump, you will find the following:</p>
<ul>
<li>the untouched String remains in memory fully intact</li>
<li>the String#clear'ed String remains to a large extent, typically the<br>
first character is missing - so if you typed "PASSWORD", search for<br>
"ASSWORD" (unintentional pun) instead</li>
<li>The String#clear_secure'ed will have been completely erased, no<br>
traces remain</li>
</ul>
<p>My questions:</p>
<ol>
<li>Would you agree that we need this functionality?</li>
<li>Where would we ideally place it? I'm not sure whether<br>
String is the perfect place, but on the other hand, String<br>
is the only place where we have access to the implementation<br>
details.</li>
<li>Are there better alternative ways how we could achieve this?</li>
</ol>
<p>[1] <a href="http://www.schneier.com/blog/archives/2008/02/cold_boot_attac.html" class="external">http://www.schneier.com/blog/archives/2008/02/cold_boot_attac.html</a><br>
[2] <a href="http://stackoverflow.com/questions/728164/securely-erasing-password-in-memory-python" class="external">http://stackoverflow.com/questions/728164/securely-erasing-password-in-memory-python</a></p> Ruby master - Feature #5654 (Assigned): Introduce global lock to avoid concurrent requirehttps://bugs.ruby-lang.org/issues/56542011-11-21T19:51:02Znahi (Hiroshi Nakamura)nakahiro@gmail.com
<p>=begin<br>
Current implementation of "require" has locks for each file (expanded name from required feature) and serializes file loading from Threads. The first Thread acquires the lock for the file and starts loading. The second Thread waits for acquiring the lock, and when the first Thread release the lock, it acquires the lock, then returns immediately.<br>
This can cause deadlock by cross-require from Threads.</p>
<p>And code that does not properly use "require" could meet several problems;</p>
<ul>
<li>constants can be defined before they're ready for use</li>
<li>classes can be modified while they're being used</li>
<li>global state can be initialized at the same time it's in use</li>
</ul>
<p>Proposal: introduce global (per VM) lock to avoid concurrent file loading by "require" so that only one Thread can call "require" at the same time.</p>
<p>I don't have pros/cons list at this moment. Let's discuss it, too.</p>
<p>Derived from a discussion at <a class="issue tracker-4 status-6 priority-4 priority-default closed" title="Backport: Please backport thread-safe autoloading patch (Rejected)" href="https://bugs.ruby-lang.org/issues/5621">#5621</a> (thread-safe autoload)<br>
=end</p> Ruby master - Feature #5643 (Assigned): require/load options and binding optionhttps://bugs.ruby-lang.org/issues/56432011-11-17T07:41:01Ztrans (Thomas Sawyer)
<p>Current Kernel#load is defined as:</p>
<pre><code>load(filename, wrap=false)
</code></pre>
<p>I purpose that it be modified to work as option argument, e.g.</p>
<pre><code>load(filename, :wrap=>true)
</code></pre>
<p>Right off the bat this has better name connascence.</p>
<p>Then support an additional option <code>:binding</code>, such that, given:</p>
<pre><code>$ cat lib/example.rb
def a
1
end
</code></pre>
<p>then</p>
<pre><code>class X
load('example.rb', :binding=>binding)
end
X.new.a #=> 1
</code></pre>
<p>The binding option should also work with #require (which would also support option parameter) differing from #load in the it would only allow the feature to be loaded once per-binding's self regardless of being required again.</p>
<p>This ability would greatly benefit systems that need "plugin" capability. Presently, a great deal of coding has to go into simulating this functionality to create plugin systems, which are often imperfect nor robust.</p> Ruby master - Feature #5558 (Assigned): String#% strange arity errorshttps://bugs.ruby-lang.org/issues/55582011-11-03T10:25:55Ztrans (Thomas Sawyer)
<p>When the number of arguments do not match the number of % parameters, the String#% method has some odd behavior.</p>
<p>When too many, it seems to work fine, ignoring the extra arguments.</p>
<p>"%s" % [1,2] #=> "1"</p>
<p>But if <code>$DEBUG = true</code>,</p>
<p>"%s" % [1,2] #=> ArgumentError: too many arguments for format string</p>
<p>That doesn't seem right. Is it an error or isn't it?</p>
<p>For too few arguments it is always an error:</p>
<p>"%s" % [] #=> ArgumentError: too few arguments</p>
<p>Personally, I think it should use '' for missing arguments. That would make it more flexible in practice.</p>
<p>I consider the first $DEBUG issue a bug, and the later a feature. But I'll just call it a feature altogether to make things easier.</p> Ruby master - Feature #5461 (Assigned): Add pipelining to Net::HTTPhttps://bugs.ruby-lang.org/issues/54612011-10-19T07:37:41Zdrbrain (Eric Hodel)drbrain@segment7.net
<p>=begin<br>
The attached patch adds HTTP/1.1 pipelining support to Net::HTTP.</p>
<p>Pipelining is only performed on HTTP/1.1 servers. Net::HTTP will check if the server supports pipelining by using the first request in the list. The user can override this via setting (({http.pipelining = true})).</p>
<p>If a server does not support pipelining or there is an error during pipelining an error will be raised that contains the requests that not have been delivered yet and the responses that have been received.</p>
<p>The patch includes documentation explaining the fine details.</p>
<p>Example:</p>
<p>requests = []<br>
requests << Net::HTTP::Get.new('/images/bug.png')<br>
requests << Net::HTTP::Get.new('/images/date.png')<br>
requests << Net::HTTP::Get.new('/images/find.png')</p>
<p>http = Net::HTTP.new 'localhost'<br>
http.start do<br>
http.pipeline requests do |req, res|<br>
open File.basename(req.path), 'wb' do |io|<br>
io.write res.body<br>
end<br>
end<br>
end</p>
<p>Implementation notes:</p>
<ul>
<li>The current Net::HTTP tests make it very difficult to test bad behavior by servers. In test/net/http/utils.rb I introduced a method to replace Net::BufferedIO with a subclass that can behave incorrectly.</li>
<li>Net::HTTP#pipeline does not fall back to sending requests one-by-one for HTTP/1.1 servers. I think this is acceptable as the user can use existing Net::HTTP code to send requests one-by-one.</li>
</ul>
<p>=end</p> Ruby master - Feature #5445 (Assigned): Need RUBYOPT -r before ARGV -rhttps://bugs.ruby-lang.org/issues/54452011-10-14T00:47:09Ztrans (Thomas Sawyer)
<p>Libraries given by -r options in RUBYOPT should be loaded before ones in direct command line arguments.</p>
<p>I use a custom load system for development that I have been using for years and it works very well for me. But Ruby has some edge cases that prevents it from being feature complete. One of these is the order in which RUBYOPT is applied vs. -r command line option.</p>
<p>My custom loader is too large to include here, so I will simply demonstrate the problem with simple sample code:</p>
<p>$ cat req.rb<br>
p "Custom Require"</p>
<p>module Kernel<br>
alias :require0 :require</p>
<pre><code>def require(*a)
puts "Kernel#require"
p a
require0(*a)
end
class << self
alias :require0 :require
def require(*a)
puts "Kernel.require"
p a
require0(*a)
end
end
</code></pre>
<p>end</p>
<p>If we load this via RUBYOPT, the result is:</p>
<p>$ RUBYOPT=-r./req.rb ruby -rstringio -e0<br>
Custom Require</p>
<p>But if we load via -r the result is:</p>
<p>$ ruby -r./req.rb -rstringio -e0<br>
Custom Require<br>
Kernel#require<br>
["stringio"]</p>
<p>I would ask that the output of both invocations to be identical.</p>
<p>(Note, the -T option should still allow RUBYOPT to be omitted regardless.)</p> Ruby master - Feature #5434 (Assigned): Allow per-class whitelisting of methods safe to expose th...https://bugs.ruby-lang.org/issues/54342011-10-11T13:11:08Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<p>We have following pull-request.</p>
<p><a href="https://github.com/ruby/ruby/pull/50" class="external">https://github.com/ruby/ruby/pull/50</a></p>
<p>How do you feel? I can merge this if you are OK.</p> Ruby master - Feature #5389 (Assigned): New method Enumerator#iteratehttps://bugs.ruby-lang.org/issues/53892011-10-03T20:25:16Zyimutang (Joey Zhou)
<p>If we want to iterate over the elements of a enumerable object with <em>multiple</em> blocks, we can use the Enumerator class.</p>
<p>A method 'iterate' is required, we can write it in Ruby:</p>
<pre><code>class Enumerator
def iterate
yield_value = self.next
return_value = yield yield_value
self.feed return_value
self
end
end
</code></pre>
<p>Well, here is an example:</p>
<pre><code>array = (1..10).to_a
enum = array.map!
loop do
enum.iterate {|n| n + 10 }
enum.iterate {|n| n * 2 }
enum.iterate {|n| -n }
end
p array # => [11, 4, -3, 14, 10, -6, 17, 16, -9, 20]
</code></pre>
<p>We want to map an array: the 1st element use blk1, the 2nd use blk2, the 3rd use blk3...</p>
<p>I think this Enumerator#iterate method is sometimes useful, so would you please introduce it into the language core?</p> Ruby master - Feature #5310 (Assigned): Integral objectshttps://bugs.ruby-lang.org/issues/53102011-09-13T10:15:48Zmrkn (Kenta Murata)muraken@gmail.com
<p>I believe it is ambiguous what object can behave as an integral number.<br>
I don't think the current use of Object#to_int isn't appropriate for this purpose.</p>
<p>The most understandable example is Float#to_int.<br>
It should raise error for all float values because they always have uncertainty,<br>
but it doesn't and returns an integral part of it.</p>
<p>I propose to change the use of Object#to_int for the next release of Ruby.<br>
I recommend the following specification changes:</p>
<p>(1) Remove to_int method from Float and BigDecimal.<br>
(2) Rational#to_int returns an Integer only if its denominator is 1. Otherwise, it raises an appropriate error.<br>
(3) Complex#to_int returns the result of to_int of its real part only if its imaginary part is exactly zero (0.0 isn't exactly zero).</p>
<p>If anyone have another idea, please give me your comment.</p> Ruby master - Feature #5133 (Assigned): Array#unzip as an alias of Array#transposehttps://bugs.ruby-lang.org/issues/51332011-08-01T18:30:03Zmrkn (Kenta Murata)muraken@gmail.com
<p>Array#zip の逆は Array#transpose なんですけど、<br>
この対応関係が非常に分かり難いなと思いました。</p>
<p>Haskell には zip の逆をやる関数として unzip が用意されています。<br>
unzip という名前は、「zip の逆をやりたい」と思ったときに<br>
(transpose よりは) 思い付きやすい名前だと思います。</p>
<p>ということで Array#unzip を Array#transpose のエイリアスとして<br>
導入してはどうでしょう?</p>
<p>以下パッチです:</p>
<p>diff --git a/array.c b/array.c<br>
index 8caad66..dc411b7 100644<br>
--- a/array.c<br>
+++ b/array.c<br>
@@ -4720,6 +4720,7 @@ Init_Array(void)<br>
rb_define_method(rb_cArray, "reject!", rb_ary_reject_bang, 0);<br>
rb_define_method(rb_cArray, "zip", rb_ary_zip, -1);<br>
rb_define_method(rb_cArray, "transpose", rb_ary_transpose, 0);</p>
<ul>
<li>rb_define_alias(rb_cArray, "unzip", "transpose");<br>
rb_define_method(rb_cArray, "replace", rb_ary_replace, 1);<br>
rb_define_method(rb_cArray, "clear", rb_ary_clear, 0);<br>
rb_define_method(rb_cArray, "fill", rb_ary_fill, -1);</li>
</ul> Ruby master - Feature #5007 (Assigned): Proc#call_under: Unifying instance_eval and instance_exechttps://bugs.ruby-lang.org/issues/50072011-07-09T23:26:49Zjudofyr (Magnus Holm)judofyr@gmail.com
<p>I'm proposing a method called <code>Proc#call_under</code> (the name could be<br>
discussed) which both unifies <code>instance_eval</code> and <code>instance_exec</code>, and makes<br>
it possible to call a <code>Proc</code> with a block and a scope:</p>
<p><code>Proc#call_under(self, *args, &blk)</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">proc</span> <span class="p">{</span> <span class="nb">self</span> <span class="p">}.</span><span class="nf">call_under</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># => 1</span>
<span class="nb">proc</span> <span class="p">{</span> <span class="o">|</span><span class="n">a</span><span class="o">|</span> <span class="nb">self</span> <span class="o">+</span> <span class="n">a</span> <span class="p">}.</span><span class="nf">call_under</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="c1"># => 3</span>
<span class="nb">proc</span> <span class="p">{</span> <span class="o">|&</span><span class="n">b</span><span class="o">|</span> <span class="nb">self</span> <span class="o">+</span> <span class="n">b</span><span class="p">.</span><span class="nf">call</span> <span class="p">}.</span><span class="nf">call_under</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="p">{</span> <span class="mi">2</span> <span class="p">}</span> <span class="c1"># => 4</span>
</code></pre> Ruby master - Feature #4924 (Assigned): mkmf have_header fails with C++ headershttps://bugs.ruby-lang.org/issues/49242011-06-24T12:09:56Zadgar (Michael Edgar)michael.j.edgar@dartmouth.edu
<p>=begin<br>
When a user calls (({have_header('some_cpp_header.h')})), and then header includes a line such as(({ #include })), mkmf will fail.</p>
<p>An example run follows:</p>
<ul>
<li>
<p>extconf.rb</p>
<p>require 'mkmf'<br>
have_library('stdc++')<br>
have_header('BasicBlock.h')<br>
create_makefile('laser/BasicBlock')</p>
</li>
<li>
<p>mkmf.log<br>
have_header: checking for BasicBlock.h... -------------------- no</p>
<p>"gcc -E -I/Users/michaeledgar/.rvm/rubies/ruby-1.9.2-head/include/ruby-1.9.1/x86_64-darwin10.7.0 -I/Users/michaeledgar/.rvm/rubies/ruby-1.9.2-head/include/ruby-1.9.1/ruby/backward -I/Users/michaeledgar/.rvm/rubies/ruby-1.9.2-head/include/ruby-1.9.1 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wshorten-64-to-32 -Wno-long-long -fno-common -pipe conftest.c -o conftest.i"<br>
In file included from conftest.c:3:<br>
./BasicBlock.h:4:18: error: vector: No such file or directory<br>
./BasicBlock.h:5:21: error: exception: No such file or directory<br>
./BasicBlock.h:6:21: error: stdexcept: No such file or directory<br>
checked program was:<br>
/* begin <em>/<br>
1: #include "ruby.h"<br>
2:<br>
3: #include <BasicBlock.h><br>
/</em> end */</p>
</li>
</ul>
<p>The issue here is that the temporary file created to perform the header test is ((%conftest.c%)), not ((%conftest.cc%)) or ((%conftest.cpp%)). Changing the<br>
name of the file and re-running gcc gives success.</p>
<p>In ((%mkmf.rb%)), have_header executes cpp_command, which creates the shell command to run. However, cpp_command uses the constant (({CONFTEST_C = "conftest.c"})). It should use a new constant, (({CONFTEST_CPP = "conftest.cc"})).</p>
<p>I've attached a patch that does this as expected. Tests pass; I'm unsure precisely how to construct<br>
a test case that would be appropriate for the Ruby trunk. There are very few guiding examples in the<br>
existing test suite.</p> Ruby master - Feature #4831 (Assigned): Integer#prime_factorshttps://bugs.ruby-lang.org/issues/48312011-06-06T00:33:11Zmame (Yusuke Endoh)mame@ruby-lang.org
<p>Hello,</p>
<p>lib/prime provides Integer#prime_division, but I always forget the name.<br>
I think that #prime_factors is more suitable. I'd like to hear opinions<br>
of English natives. What do you think?</p>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@tsg.ne.jp" class="email">mame@tsg.ne.jp</a></p> Ruby master - Feature #4824 (Assigned): Provide method Kernel#executed?https://bugs.ruby-lang.org/issues/48242011-06-04T19:59:21Zlazaridis.com (Lazaridis Ilias)ilias@lazaridis.com
<p>The current construct to execute main code looks not very elegant:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">if</span> <span class="kp">__FILE__</span> <span class="o">==</span> <span class="vg">$0</span>
<span class="n">my_main</span><span class="p">()</span> <span class="c1"># call any method or execute any code</span>
<span class="k">end</span>
</code></pre>
<p>With a <code>Kernel#executed?</code> method, this would become more elegant:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">if</span> <span class="n">executed?</span>
<span class="c1">#do this</span>
<span class="c1">#do that</span>
<span class="n">my_main</span><span class="p">()</span>
<span class="k">end</span>
</code></pre>
<p>or</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">main</span><span class="p">()</span> <span class="k">if</span> <span class="n">executed?</span>
</code></pre>
<p>This addition would not break any existent behaviour.</p> Ruby master - Feature #4592 (Assigned): Tempfileを直接保存したいhttps://bugs.ruby-lang.org/issues/45922011-04-21T16:43:31Zxibbar (Takeyuki FUJIOKA)xibbar@gmail.com
<p>=begin<br>
Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、<br>
ファイルが消えてしまいます。<br>
Tempfileのデータを保存するために<br>
一旦読みだして、書き込み用に別ファイルを開いて、<br>
そこに書きこまなければいけません。<br>
これが小さいファイルだったらいいのですが、<br>
大きいファイルになると、<br>
Tempfile#save みたいなメソッドを用意して、<br>
closeと同時に保存ができると、<br>
読みだして書きこむという無駄をなくすことができます。<br>
10MB程度だったらいいのですが、500MとかのTempfileだと<br>
かなり有効なメソッドだと思います。</p>
<p>#save とか #save! とか、何がいいかは議論の余地があると思います。<br>
=end</p> Ruby master - Feature #4521 (Assigned): NoMethodError#message may take very long to executehttps://bugs.ruby-lang.org/issues/45212011-03-25T04:59:14Zadiel.mittmann (Adiel Mittmann)adiel@inf.ufsc.br
<p>=begin<br>
When a non-existing method is called on an object, NoMethodError is risen. If you call #message, however, your code may use up all CPU for a very long time (in my case, up to a few minutes).</p>
<p>I narrowed the problem down to this code in error.c (SVN snapshot) in the function name_err_mesg_to_str():</p>
<p>d = rb_protect(rb_inspect, obj, 0);<br>
if (NIL_P(d) || RSTRING_LEN(d) > 65) {<br>
d = rb_any_to_s(obj);<br>
}</p>
<p>The problem is that, for a complex object, #inspect may take very long to execute, only to have its results thrown away because they will be larger than 65 characters.</p>
<p>Of course I can write a #to_s for all my objects, but the point is that I didn't call #to_s or #inspect, I called #message on an exception object, which then takes a few minutes just to return a short string.</p>
<p>Needless to say, this might be easy to spot in a simple example, but once you're writing a web application that suddenly freezes for one minute with no apparent reason, you're all but clueless as to what's going on. (The first time this happened, I didn't even know that something would eventually show up on the screen -- I thought it was an infinite loop).</p>
<p>Here's an example code that shows this behavior:</p>
<p>require 'nokogiri'<br>
class A<br>
def x<br>
@xml = Nokogiri::XML(File.new('baz.xml', 'rb').read())<br>
foo()<br>
end<br>
end<br>
A.new().x()<br>
a.x</p>
<p>Here, the time it takes for Ruby to print out the message that #foo doesn't exist is proportional to the size of baz.xml.</p>
<p>As a comparison, Python doesn't seem to do this. Take the following code:</p>
<p>class Test:<br>
def <strong>str</strong>(self):<br>
return "hello"<br>
a = Test()<br>
print a<br>
print a.x()</p>
<p>If you execute it, this is the result:</p>
<p>hello<br>
Traceback (most recent call last):<br>
File "test.py", line 6, in <br>
print a.x()<br>
AttributeError: Test instance has no attribute 'x'</p>
<p>It uses the method <strong>str</strong> to convert the object to a string when necessary, but doesn't use it when printing out the message stating that the attribute doesn't exist.</p>
<p>One obvious way to fix this would be to always print out the simpler representation given by rb_any_to_s.<br>
=end</p> Ruby master - Feature #2324 (Assigned): Dir instance methods for relative pathhttps://bugs.ruby-lang.org/issues/23242009-11-02T17:48:30Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<p>なかだです。</p>
<p><a href="http://www.ipa.go.jp/security/fy20/reports/tech1-tg/2_05.html" class="external">http://www.ipa.go.jp/security/fy20/reports/tech1-tg/2_05.html</a> を<br>
みて思い出したんですが、相対パスを使う<code>Dir</code>のインスタンスメソッド<br>
はどうでしょうか。実装はmvmブランチにあります。</p>
<pre><code>$ ./ruby -v -e 'p Dir.open("ext"){|d|d.open("extmk.rb"){|f|f.gets}}'
ruby 1.9.1 (2008-12-25 mvm 20976) [i686-linux]
"#! /usr/local/bin/ruby\n"
$ mkdir tmp
$ touch tmp/x tmp/y
$ ./ruby -e 'p Dir.open("tmp"){|d|d.unlink("x")}'
0
$ ls tmp/
y
</code></pre>
<p>--<br>
--- 僕の前にBugはない。<br>
--- 僕の後ろにBugはできる。<br>
中田 伸悦</p>