Ruby Issue Tracking System: Issueshttps://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112018-01-27T17:26:32ZRuby Issue Tracking System
Redmine 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 - 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 #13610 (Assigned): IPAddr doesn't provide helpful methods to get the subnet...https://bugs.ruby-lang.org/issues/136102017-05-29T09:57:09Zx89 (David John)ruby-lang@vaunt.eu
<p>I've implemented it myself using some "wild" code around the .inspect or default return from an IPAddr object from ipadr.rb</p>
<p>It would be nice to, once having loaded an IP range, to then be able to get its subnet, its IP and its CIDR.</p>
<p>I've created a PR: <a href="https://github.com/ruby/ruby/pull/1636" class="external">https://github.com/ruby/ruby/pull/1636</a> (although it's failing, not entirely sure why as Travis works fine on localhost!).</p>
<p>David</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 #13508 (Assigned): How remove/refactor code related mathn library.https://bugs.ruby-lang.org/issues/135082017-04-25T07:23:26Zhsbt (Hiroshi SHIBATA)hsbt@ruby-lang.org
<p>I removed mathn library at r58413 and r58432.</p>
<p>I have some concerns related mathn library. This issue is reminder for this concern.</p>
<ol>
<li>Still remains conditions for mathn loaded. ex. <a href="https://github.com/ruby/ruby/blob/trunk/array.c#L5755" class="external">https://github.com/ruby/ruby/blob/trunk/array.c#L5755</a>
</li>
<li>{complex,rational}.c have {nucomp,nurat}_canonicalization methods for mathn.</li>
<li>lib/cmath.rb have workaround code for mathn see. <a href="https://github.com/ruby/ruby/blob/trunk/lib/cmath.rb#L27" class="external">https://github.com/ruby/ruby/blob/trunk/lib/cmath.rb#L27</a>
</li>
</ol>
<p>I continue to discuss concerns to <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/482">@mrkn (Kenta Murata)</a></p> Ruby master - Feature #13388 (Assigned): gc.c: Add GC.get_parameters and .set_parametershttps://bugs.ruby-lang.org/issues/133882017-03-29T10:03:24Zmakimoto (Shimpei Makimoto)s@makimoto.org
<p>These methods are for inspecting and modifying MRI's GC parameters. It may be<br>
useful for realtime parameter tuning with GC.stat, user requests and so on.</p>
<p>This work is done by Tomohiro Moro (@slightair) and me (<a class="user active user-mention" href="https://bugs.ruby-lang.org/users/6929">@makimoto (Shimpei Makimoto)</a>).</p>
<p>GH issue: <a href="https://github.com/ruby/ruby/pull/1572" class="external">https://github.com/ruby/ruby/pull/1572</a></p>
<p>We're trying this patch with our environments and report here.</p> Ruby master - Feature #13252 (Assigned): C API for creating strings without copyinghttps://bugs.ruby-lang.org/issues/132522017-02-25T00:19:15Ztenderlovemaking (Aaron Patterson)tenderlove@ruby-lang.org
<p>Hi,</p>
<p>I'd like to have a C API that allows me to create String objects without copying the underlying <code>char *</code>. Basically a C API similar to the <code>rb_str_new_static</code>, but have the GC free the underlying <code>char *</code> when the object dies. The use case is that at work we have C libraries that allocate <code>char *</code> and we want to pass those to Ruby land without copying the buffer. Here is an example of what we're doing now:</p>
<p><a href="https://github.com/arthurnn/memcached/commit/1886546944b420dc6953096ba1f5eae772001e31#diff-f508f9b8263ea397534b2b3f8efed987R147" class="external">https://github.com/arthurnn/memcached/commit/1886546944b420dc6953096ba1f5eae772001e31#diff-f508f9b8263ea397534b2b3f8efed987R147</a></p>
<p>I'd like it if there was a public API for doing something like this.</p>
<p>Thank you!</p>
<p>P.S. I am sure I can't be the first to ask for this, but I couldn't find a similar issue in RedMine, so if this has been answered I apologize.<br>
P.P.S. I've added a patch for kind of what I want.</p> Ruby master - Feature #13047 (Assigned): Use String literal instead of `String#+` for multiline p...https://bugs.ruby-lang.org/issues/130472016-12-17T14:21:49Zmtsmfm (Fumiaki Matsushima)mtsmfm@gmail.com
<p>Multiline pretty-printing of multiline strings is introduced. (<a href="https://bugs.ruby-lang.org/issues/12664" class="external">https://bugs.ruby-lang.org/issues/12664</a>)</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">></span> <span class="n">pp</span> <span class="s2">"bundler.rb"</span><span class="o">=></span> <span class="s2">"module Bundler</span><span class="se">\n</span><span class="s2"> BundlerError = Class.new(Exception)</span><span class="se">\n</span><span class="s2"> def self.setup</span><span class="se">\n</span><span class="s2"> end</span><span class="se">\n</span><span class="s2">end</span><span class="se">\n</span><span class="s2">"</span>
<span class="p">{</span><span class="s2">"bundler.rb"</span><span class="o">=></span>
<span class="s2">"module Bundler</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span>
<span class="s2">" BundlerError = Class.new(Exception)</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span>
<span class="s2">" def self.setup</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span>
<span class="s2">" end</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span>
<span class="s2">"end</span><span class="se">\n</span><span class="s2">"</span><span class="p">}</span>
</code></pre>
<p>It is awesome but we can use String literal instead of <code>String#+</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">></span> <span class="n">pp</span> <span class="s2">"bundler.rb"</span><span class="o">=></span> <span class="s2">"module Bundler</span><span class="se">\n</span><span class="s2"> BundlerError = Class.new(Exception)</span><span class="se">\n</span><span class="s2"> def self.setup</span><span class="se">\n</span><span class="s2"> end</span><span class="se">\n</span><span class="s2">end</span><span class="se">\n</span><span class="s2">"</span>
<span class="p">{</span><span class="s2">"bundler.rb"</span><span class="o">=></span>
<span class="s2">"module Bundler</span><span class="se">\n</span><span class="s2">"</span> <span class="p">\</span>
<span class="s2">" BundlerError = Class.new(Exception)</span><span class="se">\n</span><span class="s2">"</span> <span class="p">\</span>
<span class="s2">" def self.setup</span><span class="se">\n</span><span class="s2">"</span> <span class="p">\</span>
<span class="s2">" end</span><span class="se">\n</span><span class="s2">"</span> <span class="p">\</span>
<span class="s2">"end</span><span class="se">\n</span><span class="s2">"</span><span class="p">}</span>
</code></pre>
<p>It seems that <code>pp</code> want to output evaluable snippet but we can override <code>String#+</code> so it may not work well.</p>
<p>Non-broken String will be:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">></span> <span class="n">pp</span> <span class="s2">"bundler.rb"</span><span class="o">=></span> <span class="s2">"module Bundler</span><span class="se">\n</span><span class="s2">end</span><span class="se">\n</span><span class="s2">"</span>
<span class="p">{</span><span class="s2">"bundler.rb"</span><span class="o">=></span> <span class="s2">"module Bundler</span><span class="se">\n</span><span class="s2">"</span> <span class="s2">"end</span><span class="se">\n</span><span class="s2">"</span><span class="p">}</span>
</code></pre>
<p>How do you think?</p>
<hr>
<p>I tried to write patch but I can't find a way to append "" to broken line only by current PP's API.</p> Ruby master - Feature #12676 (Assigned): Significant performance increase, and code conciseness, ...https://bugs.ruby-lang.org/issues/126762016-08-15T01:48:12Zjzakiya (Jabari Zakiya)
<p>I earlier posted code to simplify the prime_division method in prime.rb.<br>
This made the code much more concise and readable/understandable, while<br>
also providing a small speed increase.</p>
<p>The code presented here for prime_division2 maintains the conciseness and<br>
readability, but uses a different/simpler algorithm to provide a significant<br>
speed increase over the current implementation of prime_division in prime.rb.</p>
<p>Timings for selected large primes are provided, run on CRuby 2.3.1.<br>
System: System76 3.5GHz I7 cpu laptop, Linux 64-bit OS in Virtual Box.</p>
<pre><code>n1 = 100_000_000_000_000_003
n2 = 200_000_000_000_000_003
n3 = 1_000_000_000_000_000_003
n1 n2 n3
prime_division 23.7 33.5 74.6
prime_division1 22.9 32.2 72.8
prime_division2 14.8 20.5 45.8
</code></pre>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">tm</span><span class="p">;</span> <span class="n">s</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span><span class="p">;</span> <span class="k">yield</span><span class="p">;</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span> <span class="o">-</span> <span class="n">s</span> <span class="k">end</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">015</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="n">n</span> <span class="o">=</span> <span class="mi">100_000_000_000_000_003</span><span class="p">;</span> <span class="n">tm</span><span class="p">{</span> <span class="n">n</span><span class="p">.</span><span class="nf">prime_division</span> <span class="p">}</span>
<span class="o">=></span> <span class="mf">23.730239721</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">016</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="n">n</span> <span class="o">=</span> <span class="mi">100_000_000_000_000_003</span><span class="p">;</span> <span class="n">tm</span><span class="p">{</span> <span class="n">n</span><span class="p">.</span><span class="nf">prime_division1</span> <span class="p">}</span>
<span class="o">=></span> <span class="mf">22.877657172</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">017</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="n">n</span> <span class="o">=</span> <span class="mi">100_000_000_000_000_003</span><span class="p">;</span> <span class="n">tm</span><span class="p">{</span> <span class="n">n</span><span class="p">.</span><span class="nf">prime_division2</span> <span class="p">}</span>
<span class="o">=></span> <span class="mf">14.758561827</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">01</span><span class="mi">8</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="n">n</span> <span class="o">=</span> <span class="mi">200_000_000_000_000_003</span><span class="p">;</span> <span class="n">tm</span><span class="p">{</span> <span class="n">n</span><span class="p">.</span><span class="nf">prime_division</span> <span class="p">}</span>
<span class="o">=></span> <span class="mf">33.502851342</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">01</span><span class="mi">9</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="n">n</span> <span class="o">=</span> <span class="mi">200_000_000_000_000_003</span><span class="p">;</span> <span class="n">tm</span><span class="p">{</span> <span class="n">n</span><span class="p">.</span><span class="nf">prime_division1</span> <span class="p">}</span>
<span class="o">=></span> <span class="mf">32.23911595</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">020</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="n">n</span> <span class="o">=</span> <span class="mi">200_000_000_000_000_003</span><span class="p">;</span> <span class="n">tm</span><span class="p">{</span> <span class="n">n</span><span class="p">.</span><span class="nf">prime_division2</span> <span class="p">}</span>
<span class="o">=></span> <span class="mf">20.476660683</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">021</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="n">n</span> <span class="o">=</span> <span class="mi">1_000_000_000_000_000_003</span><span class="p">;</span> <span class="n">tm</span><span class="p">{</span> <span class="n">n</span><span class="p">.</span><span class="nf">prime_division</span> <span class="p">}</span>
<span class="o">=></span> <span class="mf">74.630244055</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">022</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="n">n</span> <span class="o">=</span> <span class="mi">1_000_000_000_000_000_003</span><span class="p">;</span> <span class="n">tm</span><span class="p">{</span> <span class="n">n</span><span class="p">.</span><span class="nf">prime_division1</span> <span class="p">}</span>
<span class="o">=></span> <span class="mf">72.778948947</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">023</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="n">n</span> <span class="o">=</span> <span class="mi">1_000_000_000_000_000_003</span><span class="p">;</span> <span class="n">tm</span><span class="p">{</span> <span class="n">n</span><span class="p">.</span><span class="nf">prime_division2</span> <span class="p">}</span>
<span class="o">=></span> <span class="mf">45.802756121</span>
</code></pre>
<ol>
<li>
<p>Current code for prime_division in prime.rb.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">prime_division</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">generator</span> <span class="o">=</span> <span class="no">Prime</span><span class="o">::</span><span class="no">Generator23</span><span class="p">.</span><span class="nf">new</span><span class="p">)</span>
<span class="k">raise</span> <span class="no">ZeroDivisionError</span> <span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="mi">0</span>
<span class="k">if</span> <span class="n">value</span> <span class="o"><</span> <span class="mi">0</span>
<span class="n">value</span> <span class="o">=</span> <span class="o">-</span><span class="n">value</span>
<span class="n">pv</span> <span class="o">=</span> <span class="p">[[</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">]]</span>
<span class="k">else</span>
<span class="n">pv</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">end</span>
<span class="n">generator</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">prime</span><span class="o">|</span>
<span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="p">(</span><span class="n">value1</span><span class="p">,</span> <span class="n">mod</span> <span class="o">=</span> <span class="n">value</span><span class="p">.</span><span class="nf">divmod</span><span class="p">(</span><span class="n">prime</span><span class="p">)</span>
<span class="n">mod</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">value1</span>
<span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">end</span>
<span class="k">if</span> <span class="n">count</span> <span class="o">!=</span> <span class="mi">0</span>
<span class="n">pv</span><span class="p">.</span><span class="nf">push</span> <span class="p">[</span><span class="n">prime</span><span class="p">,</span> <span class="n">count</span><span class="p">]</span>
<span class="k">end</span>
<span class="k">break</span> <span class="k">if</span> <span class="n">value1</span> <span class="o"><=</span> <span class="n">prime</span>
<span class="k">end</span>
<span class="k">if</span> <span class="n">value</span> <span class="o">></span> <span class="mi">1</span>
<span class="n">pv</span><span class="p">.</span><span class="nf">push</span> <span class="p">[</span><span class="n">value</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span>
<span class="k">end</span>
<span class="n">pv</span>
<span class="k">end</span>
</code></pre>
</li>
<li>
<p>Code simplification for current algorithm, increases conciseness/readability, with slight speedup.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">prime_division1</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">generator</span> <span class="o">=</span> <span class="no">Prime</span><span class="o">::</span><span class="no">Generator23</span><span class="p">.</span><span class="nf">new</span><span class="p">)</span>
<span class="k">raise</span> <span class="no">ZeroDivisionError</span> <span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="mi">0</span>
<span class="n">pv</span> <span class="o">=</span> <span class="n">value</span> <span class="o"><</span> <span class="mi">0</span> <span class="p">?</span> <span class="p">[[</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">]]</span> <span class="p">:</span> <span class="p">[]</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="p">.</span><span class="nf">abs</span>
<span class="n">generator</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">prime</span><span class="o">|</span>
<span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="p">(</span><span class="n">value1</span><span class="p">,</span> <span class="n">mod</span> <span class="o">=</span> <span class="n">value</span><span class="p">.</span><span class="nf">divmod</span><span class="p">(</span><span class="n">prime</span><span class="p">);</span> <span class="n">mod</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">value1</span>
<span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">end</span>
<span class="n">pv</span><span class="p">.</span><span class="nf">push</span> <span class="p">[</span><span class="n">prime</span><span class="p">,</span> <span class="n">count</span><span class="p">]</span> <span class="k">unless</span> <span class="n">count</span> <span class="o">==</span> <span class="mi">0</span>
<span class="k">break</span> <span class="k">if</span> <span class="n">prime</span> <span class="o">></span> <span class="n">value1</span>
<span class="k">end</span>
<span class="n">pv</span><span class="p">.</span><span class="nf">push</span> <span class="p">[</span><span class="n">value</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="n">value</span> <span class="o">></span> <span class="mi">1</span>
<span class="n">pv</span>
<span class="k">end</span>
</code></pre>
</li>
<li>
<p>Change of algorithm, maintains conciseness/readability with significant speed increase.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">prime_division2</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">generator</span> <span class="o">=</span> <span class="no">Prime</span><span class="o">::</span><span class="no">Generator23</span><span class="p">.</span><span class="nf">new</span><span class="p">)</span>
<span class="k">raise</span> <span class="no">ZeroDivisionError</span> <span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="mi">0</span>
<span class="n">pv</span> <span class="o">=</span> <span class="n">value</span> <span class="o"><</span> <span class="mi">0</span> <span class="p">?</span> <span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="p">:</span> <span class="p">[]</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="p">.</span><span class="nf">abs</span>
<span class="n">sqrt_value</span> <span class="o">=</span> <span class="no">Math</span><span class="p">.</span><span class="nf">sqrt</span><span class="p">(</span><span class="n">value</span><span class="p">).</span><span class="nf">to_i</span>
<span class="n">generator</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">prime</span><span class="o">|</span>
<span class="k">break</span> <span class="k">if</span> <span class="n">prime</span> <span class="o">></span> <span class="n">sqrt_value</span>
<span class="k">while</span> <span class="n">value</span> <span class="o">%</span> <span class="n">prime</span> <span class="o">==</span> <span class="mi">0</span>
<span class="n">pv</span> <span class="o"><<</span> <span class="n">prime</span>
<span class="n">value</span> <span class="o">/=</span> <span class="n">prime</span>
<span class="n">sqrt_value</span> <span class="o">=</span> <span class="no">Math</span><span class="p">.</span><span class="nf">sqrt</span><span class="p">(</span><span class="n">value</span><span class="p">).</span><span class="nf">to_i</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">pv</span> <span class="o"><<</span> <span class="n">value</span> <span class="k">if</span> <span class="n">value</span> <span class="o">></span> <span class="mi">1</span>
<span class="n">pv</span><span class="p">.</span><span class="nf">group_by</span> <span class="p">{</span><span class="o">|</span><span class="n">prm</span><span class="o">|</span> <span class="n">prm</span> <span class="p">}.</span><span class="nf">map</span><span class="p">{</span><span class="o">|</span><span class="n">prm</span><span class="p">,</span> <span class="n">exp</span><span class="o">|</span> <span class="p">[</span><span class="n">prm</span><span class="p">,</span> <span class="n">exp</span><span class="p">.</span><span class="nf">size</span><span class="p">]</span> <span class="p">}</span>
<span class="k">end</span>
</code></pre>
</li>
</ol> Ruby master - Feature #12656 (Assigned): Expand short paths with File.expand_pathhttps://bugs.ruby-lang.org/issues/126562016-08-04T20:06:47Zdavispuh (Dāvis Mosāns)
<p>Currently File.expand_path expands short path only if it's last part.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">puts</span> <span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="s1">'C:/VERYLO~1'</span><span class="p">)</span>
<span class="nb">puts</span> <span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="s1">'C:/VERYLO~1/OTHERL~1'</span><span class="p">)</span>
</code></pre>
<p>Produces</p>
<pre><code>C:/VeryLongName12345
C:/VERYLO~1/OtherLongName54321
</code></pre>
<p>With attached patch it will always be long path</p>
<pre><code>C:/VeryLongName12345
C:/VeryLongName12345/OtherLongName54321
</code></pre>
<p>This also fixes TestDir#test_glob test because it was failing due short path.</p> Ruby 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 #12497 (Assigned): GMP version of divmod may be slowerhttps://bugs.ruby-lang.org/issues/124972016-06-16T17:04:12Zmame (Yusuke Endoh)mame@ruby-lang.org
<p><a href="https://benchmarksgame.alioth.debian.org/u64q/program.php?test=pidigits&lang=yarv&id=3" class="external">The benchmark program <code>pidigits.rb</code></a> runs faster if USE_GMP is disabled for divmod.</p>
<pre><code>$ time ./miniruby.orig pidigits.rb 10000 > /dev/null
real 0m5.932s
user 0m5.740s
sys 0m0.188s
</code></pre>
<pre><code>$ time ./miniruby.patched pidigits.rb 10000 > /dev/null
real 0m3.212s
user 0m3.056s
sys 0m0.152s
</code></pre>
<pre><code>diff --git a/bignum.c b/bignum.c
index 767659d..33a172e 100644
--- a/bignum.c
+++ b/bignum.c
@@ -2813,12 +2813,6 @@ rb_big_divrem_gmp(VALUE x, VALUE y)
static void
bary_divmod_branch(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
{
-#ifdef USE_GMP
- if (GMP_DIV_DIGITS < xn) {
- bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
- return;
- }
-#endif
bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
}
</code></pre>
<p>We can possibly tune performance.</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 - Bug #12040 (Assigned): [Win32] File.stat fails on a mounted volumehttps://bugs.ruby-lang.org/issues/120402016-02-01T08:13:24Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<p>On Windows, <code>File.stat</code> fails on the volume mount point directory whose name contains <code>"..."</code>.</p>
<p>Where <code>%vol%</code> is the volume ID of a new VHD volume,</p>
<pre><code>C:> set vol
\\?\Volume{3C458AE9-C8B1-11E5-A233-0800271D089F}\
C:> mkdir x...y
C:> mountvol x...y %vol%
C:> .\miniruby -e "p Dir.chdir('x...y'){File.stat('.')}" -e "p File.stat('x...y')"
#<File::Stat dev=0x2, ino=1407374883553285, mode=040755, nlink=1, uid=0, gid=0, rdev=0x2, size=4096, blksize=nil, blocks=nil, atime=2016-02-01 16:35:45 +0900, mtime=2016-02-01 16:35:45 +0900, ctime=2016-02-01 16:35:45 +0900>
-e:2:in `stat': No such file or directory @ rb_file_s_stat - x...y (Errno::ENOENT)
from -e:2:in `<main>'
</code></pre>
<p>Note that <code>Dir.chdir</code> and <code>File.stat</code> there succeed.<br>
This failures depends on the mount point name, because of <code>check_valid_dir()</code>.</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 #10481 (Assigned): Add "if" and "unless" clauses to rescue statementshttps://bugs.ruby-lang.org/issues/104812014-11-05T19:20:10Zjavawizard (Alex Boyd)alex@opengroove.org
<p>I'd like to propose a syntax change: allow boolean "if" and "unless" clauses to follow a rescue statement.</p>
<p>Consider the following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span>
<span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">1</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span><span class="o">...</span>
<span class="k">else</span>
<span class="k">raise</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>This is a fairly common way of dealing with exceptions where some condition above and beyond the exception's type determines whether the exception should be rescued. It's verbose, though, and it's not obvious at first glance exactly what conditions are being rescued, especially if "...handle error..." is more than a few lines long. I propose that the following be allowed:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span> <span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">1</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span><span class="o">...</span>
<span class="k">end</span>
</code></pre>
<p>"unless" would, of course, be allowed as well:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span> <span class="k">unless</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">2</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span><span class="o">...</span>
<span class="k">end</span>
</code></pre>
<p>A rescue statement whose boolean condition failed would be treated the same as if the exception being raised didn't match the exception being rescued, and move on to the next rescue statement:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span> <span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">1</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span> <span class="n">code</span> <span class="mi">1</span><span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span> <span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">2</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span> <span class="n">code</span> <span class="mi">2</span><span class="o">...</span>
<span class="k">end</span>
</code></pre>
<p>And finally, catch-all rescue statements would be allowed as well:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="o">=></span> <span class="n">e</span> <span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">message</span> <span class="o">==</span> <span class="s2">"some error"</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span><span class="o">...</span>
<span class="k">end</span>
</code></pre> Ruby master - Feature #10459 (Assigned): [PATCH] rfc3339 method for Timehttps://bugs.ruby-lang.org/issues/104592014-10-30T11:12:16ZAntiarchitect (Andrey Voronkov)voronkovaa@gmail.com
<p>Alias for iso8601 method for compatibility with DateTime (Ruby on Rails).</p> Ruby master - Feature #10129 (Assigned): More descriptive error message for failed net/http requestshttps://bugs.ruby-lang.org/issues/101292014-08-13T22:34:43Zxshay (Xavier Shay)contact@xaviershay.com
<p>Hello,<br>
I would like to propose the following patch:</p>
<p>Before</p>
<pre><code>2.1.2 :003 > Net::HTTP.get(URI.parse("https://arsrtrtrstsrt.com/arstr"))
SocketError: getaddrinfo: nodename nor servname provided, or not known
</code></pre>
<p>After</p>
<pre><code>2.1.2 :003 > Net::HTTP.get(URI.parse("https://arsrtrtrstsrt.com/arstr"))
SocketError: Failed to open TCP connection to arsrtrtrstsrt.com:443 (getaddrinfo: nodename nor servname provided, or not known)
</code></pre>
<p>I have an implementation with test at <a href="https://github.com/ruby/ruby/pull/700" class="external">https://github.com/ruby/ruby/pull/700</a></p>
<p>Thank you for your consideration,<br>
Xavier</p> 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 #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 #9768 (Assigned): Method that is visible only within a certain module/classhttps://bugs.ruby-lang.org/issues/97682014-04-22T09:57:35Zsawa (Tsuyoshi Sawada)
<p>Some frameworks/libraries monkeypatch their own methods on Ruby core classes like <code>String</code>, <code>Hash</code>, <code>Array</code>, etc., and that is often causing problems/concerns of name conflict.</p>
<p>Seeing that these custom methods are used only in the context of a certain module/class, I request for a way to define a method (<code>foo</code>) on a module/class (<code>A</code>) so that it will be visible only from within a specified module/class (<code>B</code>) or its descendants. The following illustrates this situation:</p>
<pre><code>A.new.foo # => undefined
class B
A.new.foo # => defined
def bar
A.new.foo # => defined
end
def self.baz
A.new.foo # => defined
end
end
class C < B
A.new.foo # => defined
def bar
A.new.foo # => defined
end
def self.baz
A.new.foo # => defined
end
end
</code></pre>
<p>I do not have a certain syntax for this in mind, but I think it can be made much simpler, compared to the complicated syntax of refinement.</p>
<p>This is reminiscent of refinement, but they are pretty much different.</p>
<p>Refinement's purpose is to let certain methods be accessible from only a certain file. A typical use case would be a library developer defining their methods to be used from within the library and making such methods inaccessible from the end user.</p>
<p>On the other hand, the idea I am proposing here is for making method accessible from any file, but only within a certain module/class. A typical use case would be defining a method to be used by an end user, but only from within a context of certain module/class.</p> Ruby master - Feature #9755 (Assigned): Thread::Backtrace::Location#defined_classhttps://bugs.ruby-lang.org/issues/97552014-04-18T09:22:23Zshugo (Shugo Maeda)
<p>I'd like Thread::Backtrace::Location#defined_class.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">X</span>
<span class="k">def</span> <span class="nf">foo</span>
<span class="nb">p</span> <span class="n">caller_locations</span><span class="p">.</span><span class="nf">first</span><span class="p">.</span><span class="nf">defined_class</span> <span class="c1">#=> Y</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Y</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="no">X</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">foo</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Y</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">bar</span>
</code></pre>
<p>nobu created a patch:</p>
<p><a href="https://github.com/nobu/ruby/compare/backtrace-self%2Bclass" class="external">https://github.com/nobu/ruby/compare/backtrace-self%2Bclass</a></p>
<p>But this patch has two problems:</p>
<ol>
<li>The patch adds Thread::Backtrace::Location#self, but it's weird that a location has self.</li>
<li>Thread::Backtrace::Location#class conflicts with Kernel#class.<br>
So I proposed defined_class as the method name.</li>
</ol> 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 - 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 - Feature #8960 (Assigned): Add Exception#backtrace_locationshttps://bugs.ruby-lang.org/issues/89602013-09-27T20:11:45Zheadius (Charles Nutter)headius@headius.com
<p>All parties agreed this would be useful to add in <a href="https://bugs.ruby-lang.org/issues/7895" class="external">https://bugs.ruby-lang.org/issues/7895</a> and ko1 suggested I file a feature against ruby-trunk. So here it is.</p>
<p>I might be able to come up with a patch, but I'm not sure when. Help wanted.</p>
<p>Can we agree this will go into 2.1?</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 #8850 (Assigned): Convert Rational to decimal stringhttps://bugs.ruby-lang.org/issues/88502013-09-02T10:02:36Znaruse (Yui NARUSE)naruse@airemix.jp
<p>On Ruby 2.1.0, decimal literal is introduced.<br>
It generates Rational but it cannot easily convert to decimal string.<br>
You know, Rational#to_f is related to this but</p>
<ul>
<li>
<p>Float is not exact number<br>
** 0.123456789123456789r.to_f.to_s #=> "0.12345678912345678"</p>
</li>
<li>
<p>it can't handle recursive decimal<br>
** (151/13r).to_f.to_s #=> "11.615384615384615"</p>
</li>
<li>
<p>the method name<br>
** to_decimal<br>
** to_decimal_string<br>
** to_s(format: :decimal)<br>
** extend sprintf</p>
</li>
<li>
<p>how does it express recursive decimal<br>
** (151/13r).to_decimal_string #=> "11.615384..."<br>
** (151/13r).to_decimal_string #=> "11.(615384)"</p>
</li>
</ul>
<p>Example implementation is following.<br>
Its result is<br>
** 0.123456789123456789r.to_f.to_s #=> "0.123456789123456789"<br>
** (151/13r).to_f.to_s #=> "11.(615384)"</p>
<pre><code>class Rational
def to_decimal_string(base=10)
n = numerator
d = denominator
r, n = n.divmod d
str = r.to_s(base)
return str if n == 0
h = {}
str << '.'
n *= base
str.size.upto(Float::INFINITY) do |i|
r, n = n.divmod d
if n == 0
str << r.to_s(base)
break
elsif h.key? n
str[h[n], 0] = '('
str << ')'
break
else
str << r.to_s(base)
h[n] = i
n *= base
end
end
str
end
end
</code></pre> Ruby master - Feature #8839 (Assigned): Class and module should return the class or module that w...https://bugs.ruby-lang.org/issues/88392013-08-31T02:57:19Zheadius (Charles Nutter)headius@headius.com
<p>With the change for <a href="https://bugs.ruby-lang.org/issues/3753" class="external">https://bugs.ruby-lang.org/issues/3753</a>, "def" forms now return the symbolic name of the method defined. Because class and module bodies just return the last expression in their bodies, this means they will now usually end up returning a symbol for the last method defined. This does not seem useful or correct.</p>
<p>I think class and module should return a reference to the class or module just opened. This would make the return value useful and consistent.</p> Ruby master - Feature #8678 (Assigned): Allow invalid string to work with regexphttps://bugs.ruby-lang.org/issues/86782013-07-24T14:47:22Znaruse (Yui NARUSE)naruse@airemix.jp
<p>Legacy Ruby 1.8 could regexp match with broken strings.<br>
People can find characters from binary data on the age.</p>
<p>After Ruby 1.9, Ruby raises Exception if it does regexp match with broken strings.<br>
So it became hard to work with character-wise regexp matching with binary data.</p>
<p>Following patch allows it with the constant Regexp::LOOSEENCODING.</p>
<p>commit eb0111ff7ae3f563ce201c4a5f724f121336d42d<br>
Author: NARUSE, Yui <a href="mailto:naruse@ruby-lang.org" class="email">naruse@ruby-lang.org</a><br>
Date: Mon Jul 22 05:37:44 2013 +0900</p>
<pre><code>* Regexp
* New constant:
* Regexp::ENCODINGLOOSE: declare execute matching even if the target string
is invalid byte sequence. [experimental]
</code></pre>
<p>diff --git a/NEWS b/NEWS<br>
index f5fe388..ade0b03 100644<br>
--- a/NEWS<br>
+++ b/NEWS<br>
@@ -35,6 +35,11 @@ with all sufficient information, see the ChangeLog file.</p>
<ul>
<li>misc
<ul>
<li>Mutex#owned? is no longer experimental.</li>
</ul>
</li>
</ul>
<p>+* Regexp</p>
<ul>
<li>
<ul>
<li>New constant:</li>
</ul>
</li>
<li>
<ul>
<li>Regexp::ENCODINGLOOSE: declare execute matching even if the target string</li>
</ul>
</li>
<li>
<pre><code> is invalid byte sequence. [experimental]
</code></pre>
</li>
<li>
</ul>
<ul>
<li>String
<ul>
<li>New methods:
<ul>
<li>String#scrub and String#scrub! verify and fix invalid byte sequence.<br>
diff --git a/re.c b/re.c<br>
index e5cc79d..230a2e0 100644<br>
--- a/re.c<br>
+++ b/re.c<br>
@@ -256,6 +256,7 @@ rb_memsearch(const void *x0, long m, const void *y0, long n, rb_encoding *enc)</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>#define REG_LITERAL FL_USER5<br>
#define REG_ENCODING_NONE FL_USER6<br>
+#define REG_ENCODING_LOOSE FL_USER7</p>
<p>#define KCODE_FIXED FL_USER4</p>
<p>@@ -263,6 +264,7 @@ rb_memsearch(const void *x0, long m, const void *y0, long n, rb_encoding *enc)<br>
(ONIG_OPTION_IGNORECASE|ONIG_OPTION_MULTILINE|ONIG_OPTION_EXTEND)<br>
#define ARG_ENCODING_FIXED 16<br>
#define ARG_ENCODING_NONE 32<br>
+#define ARG_ENCODING_LOOSE 64</p>
<p>static int<br>
char_to_option(int c)<br>
@@ -1251,7 +1253,8 @@ rb_reg_prepare_enc(VALUE re, VALUE str, int warn)<br>
{<br>
rb_encoding *enc = 0;</p>
<ul>
<li>if (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) {</li>
</ul>
<ul>
<li>if (!(RBASIC(re)->flags & REG_ENCODING_LOOSE) &&</li>
<li>
<pre><code> rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) {
rb_raise(rb_eArgError,
"invalid byte sequence in %s",
rb_enc_name(rb_enc_get(str)));
</code></pre>
</li>
</ul>
<p>@@ -2433,6 +2436,9 @@ rb_reg_initialize(VALUE obj, const char *s, long len, rb_encoding *enc,<br>
if (options & ARG_ENCODING_NONE) {<br>
re->basic.flags |= REG_ENCODING_NONE;<br>
}</p>
<ul>
<li>
<p>if (options & ARG_ENCODING_LOOSE) {</p>
</li>
<li>
<pre><code> re->basic.flags |= REG_ENCODING_LOOSE;
</code></pre>
</li>
<li>
<p>}</p>
<p>re->ptr = make_regexp(RSTRING_PTR(unescaped), RSTRING_LEN(unescaped), enc,<br>
options & ARG_REG_OPTION_MASK, err,<br>
@@ -3091,6 +3097,7 @@ rb_reg_options(VALUE re)<br>
options = RREGEXP(re)->ptr->options & ARG_REG_OPTION_MASK;<br>
if (RBASIC(re)->flags & KCODE_FIXED) options |= ARG_ENCODING_FIXED;<br>
if (RBASIC(re)->flags & REG_ENCODING_NONE) options |= ARG_ENCODING_NONE;</p>
</li>
<li>
<p>if (RBASIC(re)->flags & REG_ENCODING_LOOSE) options |= ARG_ENCODING_LOOSE;<br>
return options;<br>
}</p>
</li>
</ul>
<p>@@ -3579,6 +3586,8 @@ Init_Regexp(void)<br>
rb_define_const(rb_cRegexp, "FIXEDENCODING", INT2FIX(ARG_ENCODING_FIXED));<br>
/* see Regexp.options and Regexp.new */<br>
rb_define_const(rb_cRegexp, "NOENCODING", INT2FIX(ARG_ENCODING_NONE));</p>
<ul>
<li>
<p>/* see Regexp.options and Regexp.new */</p>
</li>
<li>
<p>rb_define_const(rb_cRegexp, "LOOSEENCODING", INT2FIX(ARG_ENCODING_LOOSE));</p>
<p>rb_global_variable(&reg_cache);</p>
</li>
</ul>
<p>diff --git a/string.c b/string.c<br>
index 1d784e3..caf0baf 100644<br>
--- a/string.c<br>
+++ b/string.c<br>
@@ -3970,7 +3970,7 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)<br>
cp = sp;<br>
str_enc = STR_ENC_GET(str);<br>
rb_enc_associate(dest, str_enc);</p>
<ul>
<li>ENC_CODERANGE_SET(dest, rb_enc_asciicompat(str_enc) ? ENC_CODERANGE_7BIT : ENC_CODERANGE_VALID);</li>
</ul>
<ul>
<li>
<p>/<em>ENC_CODERANGE_SET(dest, rb_enc_asciicompat(str_enc) ? ENC_CODERANGE_7BIT : ENC_CODERANGE_VALID);</em>/</p>
<p>do {<br>
n++;<br>
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb<br>
index 11e86ec..b8f6897 100644<br>
--- a/test/ruby/test_regexp.rb<br>
+++ b/test/ruby/test_regexp.rb<br>
@@ -8,6 +8,10 @@ class TestRegexp < Test::Unit::TestCase<br>
$VERBOSE = nil<br>
end</p>
</li>
<li>
<p>def u(str)</p>
</li>
<li>
<p>str.dup.force_encoding(Encoding::UTF_8)</p>
</li>
<li>
<p>end</p>
</li>
<li>
<p>def teardown<br>
$VERBOSE = @verbose<br>
end<br>
@@ -958,6 +962,17 @@ class TestRegexp < Test::Unit::TestCase<br>
}<br>
end</p>
</li>
<li>
<p>def test_encoding_loose</p>
</li>
<li>
<p>str = u("\x80\xE3\x81\x82\x81")</p>
</li>
<li>
<p>assert_equal(0, Regexp.new(".", Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(1, Regexp.new(u('\p{Any}'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(1, Regexp.new("\u3042", Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(1, Regexp.new(u('\p{Hiragana}'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(0, Regexp.new(u('\A.\p{Hiragana}.\z'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>str = u("\xf1\x80\xE3\x81\x82\x81")</p>
</li>
<li>
<p>assert_equal(0, Regexp.new(u('\A..\p{Hiragana}.\z'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>end</p>
</li>
<li>
<a name="This-assertion-is-for-porting-x2-tests-in-testpypy-of-Onigmo"></a>
<h1 >This assertion is for porting x2() tests in testpy.py of Onigmo.<a href="#This-assertion-is-for-porting-x2-tests-in-testpypy-of-Onigmo" class="wiki-anchor">¶</a></h1>
<p>def assert_match_at(re, str, positions, msg = nil)<br>
re = Regexp.new(re) unless re.is_a?(Regexp)</p>
</li>
</ul> Ruby master - Feature #8576 (Assigned): Add optimized method type for constant value methodshttps://bugs.ruby-lang.org/issues/85762013-06-28T23:22:32ZAnonymous
<p>I've written a patch adding a new method type (VM_METHOD_TYPE_CONSTVAL) for methods that only return a constant value. The patch significantly improves the performance of calls to these types of methods.</p>
<p>I've written a small benchmark script:</p>
<pre><code>require "benchmark"
def foo
1234
end
puts Benchmark.measure {
1_000_000.times do
foo; foo; foo; foo; foo
foo; foo; foo; foo; foo
end
}
</code></pre>
<p>Before patch:</p>
<pre><code>$ ./rb x.rb
0.620000 0.000000 0.620000 ( 0.625130)
</code></pre>
<p>After patch:</p>
<pre><code>$ ./rb x.rb
0.300000 0.000000 0.300000 ( 0.296528)
</code></pre>
<p>The patch is here: <a href="https://github.com/charliesome/ruby/compare/constant-value-methods" class="external">https://github.com/charliesome/ruby/compare/constant-value-methods</a></p> Ruby master - Feature #8536 (Assigned): Implement is_numeric? family of methodshttps://bugs.ruby-lang.org/issues/85362013-06-17T12:31:08Zwardrop (Tom Wardrop)tom@tomwardrop.com
<p>=begin<br>
I think Ruby is in dire need of a convenient method for determining whether a string can be safely converted to a number. It's a trivial problem, but with no trivial solution. The most common methods include using regex, or trying to convert the value to the desired type, rescuring any exceptions that are raised. These are not desirable by any means.</p>
<p>I propose a number of new methods be added, either to each of the number classes such as (({Integer.is_integer?})) and (({Numeric.is_numeric?})), to a single parent such as Numeric. For convenience, corresponding methods may also be added to the String class. The methods I propose are...</p>
<ul>
<li>is_numeric?</li>
<li>is_integer?</li>
<li>is_float?</li>
<li>is_rationale?</li>
</ul>
<p>With the exception of numeric, if each of the other methods return true, that value should be safe to use with the corresponding (({Integer("5")})) style methods, and (({to_i})) methods. These boolean methods should behave like the (({Integer("5")})), in that they should disregard/strip whitespace for example.</p>
<p>I think it'd make a nice feature enhancement to Ruby 2.1.<br>
=end</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 #8083 (Assigned): Exit status is limited to one-byte values which is invali...https://bugs.ruby-lang.org/issues/80832013-03-13T19:00:42Zrutsky (Vladimir Rutsky)rutsky.vladimir@gmail.com
<p>=begin<br>
Windows uses 32-bit process exit codes so Ruby incorrectly truncates them to one byte:</p>
<p>C:\Ruby193\bin>ruby -e "system('C:\windows\system32\cmd.exe /c exit 255'); puts $?.exitstatus"<br>
255</p>
<p>C:\Ruby193\bin>ruby -e "system('C:\windows\system32\cmd.exe /c exit 256'); puts $?.exitstatus"<br>
0</p>
<p>C:\Ruby193\bin>ruby -e "system('C:\windows\system32\cmd.exe /c exit 257'); puts $?.exitstatus"<br>
1</p>
<p>Similar code works correctly in Python:</p>
<p>C:\Python27>python -c "import subprocess; print subprocess.call('C:\windows\system32\cmd.exe /c exit 255')"<br>
255</p>
<p>C:\Python27>python -c "import subprocess; print subprocess.call('C:\windows\system32\cmd.exe /c exit 256')"<br>
256</p>
<p>C:\Python27>python -c "import subprocess; print subprocess.call('C:\windows\system32\cmd.exe /c exit 257')"<br>
257<br>
=end</p> Ruby master - Feature #8047 (Assigned): IPAddr makes host address with netmaskhttps://bugs.ruby-lang.org/issues/80472013-03-08T14:48:17Znori_nori (Tadanori Kojima)peach.peacher@gmail.com
<p>現状のIPAddrはネットマスク付きの場合、</p>
<pre><code>IPAddr.new("192.168.1.99/24")
=> #<IPAddr: IPv4:192.168.1.0/255.255.255.0>
</code></pre>
<p>のようにネットワークアドレスとして生成されますが、<br>
マスク付きの場合にマスクされないホストとして生成する<br>
モードを提案します<br>
(=ホストのIPアドレスとどのネットワークかを把握したい)<br>
ex.</p>
<pre><code>IPAddr.new("192.168.1.99/24")
=> #<IPAddr: IPv4:192.168.1.99/255.255.255.0>
</code></pre>
<p>newの第二引数にfamilyが指定されていれば32bitマスクのホストアドレスなので、<br>
引数がAF_INET/INET6または:Hostならばホストとして生成させます</p>
<ul>
<li>IPAddr.new(int, family)</li>
</ul>
<pre><code>IPAddr.new(3232235875, Socket::AF_INET)
=> #<IPAddr: IPv4:192.168.1.99/255.255.255.255>
</code></pre>
<ul>
<li>IPAddr.new(ip, :Host)</li>
</ul>
<pre><code>IPAddr.new("192.168.1.99/24", :Host)
=> #<IPAddr: IPv4:192.168.1.99/255.255.255.0>
</code></pre>
<p>引数の構成とシンボル名がイマイチですが既存との両立ということで<br>
以下がパッチになります</p>
<pre><code>--- ipaddr.rb.orig 2013-03-08 13:59:07.000000000 +0900
+++ ipaddr.rb 2013-03-08 14:35:06.000000000 +0900
@@ -440,7 +440,7 @@
else
raise AddressFamilyError, "unsupported address family"
end
- @addr = ((@addr >> masklen) << masklen)
+ @addr = ((@addr >> masklen) << masklen) if @host_mode == false
return self
end
@@ -477,6 +477,14 @@
raise AddressFamilyError, "unsupported address family: #{family}"
end
end
+
+ if family == :Host
+ @host_mode = true
+ family = Socket::AF_UNSPEC
+ else
+ @host_mode = false
+ end
+
prefix, prefixlen = addr.split('/')
if prefix =~ /^\[(.*)\]$/i
prefix = $1
</code></pre> Ruby master - Feature #8042 (Assigned): Add Addrinfo#socket to create a socket that is not connec...https://bugs.ruby-lang.org/issues/80422013-03-08T08:35:01Zdrbrain (Eric Hodel)drbrain@segment7.net
<p>This adds a socket method to Addrinfo to get a socket that has not been bound or connected to any address for connectionless operation.</p> Ruby master - Feature #8016 (Assigned): Alias __FILE__ and __LINE__ as methodshttps://bugs.ruby-lang.org/issues/80162013-03-05T12:16:30Zwardrop (Tom Wardrop)tom@tomwardrop.com
<p>=begin<br>
All of the previous issues discussing the new (({Kernel#<strong>dir</strong>})) method (<a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Kernel#__dir__ (Closed)" href="https://bugs.ruby-lang.org/issues/1961">#1961</a>, <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: __DIR__ revisted (Closed)" href="https://bugs.ruby-lang.org/issues/3346">#3346</a>, <a class="issue tracker-1 status-6 priority-4 priority-default closed" title="Bug: Why __dir__, not __DIR__ (Rejected)" href="https://bugs.ruby-lang.org/issues/7975">#7975</a>), never came to any conclusion regarding the naming inconsistency between the likes of (({<strong>dir</strong>})) and (({<strong>method</strong>})), and the keywords (({<strong>FILE</strong>})) and (({<strong>LINE</strong>})).</p>
<p>Should we not add (({<strong>file</strong>})) and (({<strong>line</strong>})) as methods also, and perhaps deprecate the keywords (({<strong>FILE</strong>})) and (({<strong>LINE</strong>})). This would keep it consistant with all the other double-underscore methods. To most developers who perhaps do not know Ruby as intricately as most of the people on this issue tracker, the inconsistency between (({<strong>dir</strong>})) and (({<strong>FILE</strong>})) is not just confusing by name, but the fact that one is a method and one isn't, is doubly confusing. Definitely not principle of least surprise.</p>
<p>This needs to be addressed in my opinion, either through deprecation of (({<strong>FILE</strong>})) and (({<strong>LINE</strong>})), or by keeping those keywords and simply creating Kernel method equivalents for the sake of a consistant API.</p>
<p>While on the topic, someone also suggested in one of those previous issues, to give (({<strong>dir</strong>})) an optional join argument, so you could do something like this:</p>
<pre><code>__dir__('somefile.txt') # => /Users/admin/somefile.txt
</code></pre>
<p>I'd predict that at least 90% of use cases for (({<strong>dir</strong>})) will involve joining it to another path or filename. I can't see any harm in adding this. The naming inconstancies are my main concern however. This would just be a nice bonus that takes advantage of the fact that (({<strong>dir</strong>})) is a method rather than a keyword.<br>
=end</p> Ruby master - Feature #7739 (Assigned): Define Hash#| as Hash#reverse_merge in Railshttps://bugs.ruby-lang.org/issues/77392013-01-24T21:57:20Zalexeymuranov (Alexey Muranov)
<p>=begin<br>
I suggest for to define (({Hash#|})) as (({Hash#reverse_merge})) in ((<em>Rails</em>)), in my opinion this would correspond nicely to (({Set#|})), to the logical (({#||})) and to the bitwise (({#|})):</p>
<p>{ :a => 1, :b => 2 } | { :b => 1, :c => 2 } # => { :a => 1, :b => 1, :c => 2 }<br>
=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 #7503 (Assigned): make timeout.rb async-interrupt safe by defaulthttps://bugs.ruby-lang.org/issues/75032012-12-03T22:33:41Zkosaki (Motohiro KOSAKI)kosaki.motohiro@gmail.com
<p>Hi</p>
<p>Again and again we discussed, current timeout.rb is very dangerous because ExitException interrupt argument code and unwind call stack immediately.<br>
It may prevent to run ensure block and makes resource leak.</p>
<p>I proposed change default to interrupted only on blocking point.</p>
<p>patch is here.<br>
<a href="https://gist.github.com/4195015" class="external">https://gist.github.com/4195015</a></p>
<p>I also propse to add 'immediate' optional argument because it may help to make a workaround timeout.rb + zero blocking point corner case.</p>
<p>What do you think?</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 #7436 (Assigned): Allow for a "granularity" flag for backtrace_locationshttps://bugs.ruby-lang.org/issues/74362012-11-26T07:06:40Zsam.saffron (Sam Saffron)sam.saffron@gmail.com
<p>related to <a href="http://bugs.ruby-lang.org/issues/7051" class="external">http://bugs.ruby-lang.org/issues/7051</a></p>
<p>Sometimes one need less information (or more information) associated with backtraces.</p>
<p>It would be nice if one could send in a separate flag informing the VM about the granularity of information required, eg:</p>
<p>caller_locations(0,-current_depth, BacktraceInfo::Label & BacktraceInfo::Lineno)</p>
<p>This allows for one to take quicker backtraces if they need less information, additionally BacktraceInfo::Bindings and BacktraceInfo::Klass could be added which allow you to gather more information for heavy profiling / diagnostics.</p> Ruby master - Feature #7412 (Assigned): Pathname#relative_path_from does not support mixed direct...https://bugs.ruby-lang.org/issues/74122012-11-20T20:15:24Z7er (Syver Enstad)syver.enstad@gmail.com
<p>=begin<br>
The support for mixing backslashes and forward slashes in the pathname module in the standard library seems to be broken on windows</p>
<pre><code>require 'pathname'
base = Pathname.new("c:\\")
filepath = Pathname.new("c:/foo/bar/file.ext")
base.relative_path_from(filepath)
</code></pre>
<p>raises <code>ArgumentError: different prefix: "c:\\" and "c:/foo/bar/file.ext"</code></p>
<p>Changing filepath to contain backslashes fixes the problem</p>
<pre><code>filepath = Pathname.new("c:\\foo\\bar\\file.ext")
base.relative_path_from(filepath)
</code></pre>
<p><code>=> #<Pathname:../../..></code><br>
=end</p> Ruby master - Feature #7362 (Assigned): Adding Pathname#start_with?https://bugs.ruby-lang.org/issues/73622012-11-15T22:38:40Zaef (Alexander E. Fischer)aef@raxys.net
<p>If a Pathname starts with another Pathname, that means that the former Pathname lies below the latter Pathname, as long as both Pathnames are interpreted from the same location or both are given as absolute.</p>
<p>Therefore I would like to see a method #start_with? just like the one on String but for Pathnames.</p>
<p>If you like the idea, just tell me. I will provide a patch then.</p> 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 #7314 (Assigned): Convert Proc to Lambda doesn't work in MRIhttps://bugs.ruby-lang.org/issues/73142012-11-09T01:30:19Zschneems (Richard Schneeman)
<p>I have code where I need to convert a proc to a lambda (i need to be able to return out of the block). I would expect that passing a proc into a lambda to return a lambda. When I run this code on MRI i do not get the result I would expect</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">my_proc</span> <span class="o">=</span> <span class="nb">proc</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="p">}</span>
<span class="n">my_lambda</span> <span class="o">=</span> <span class="nb">lambda</span> <span class="o">&</span><span class="n">my_proc</span>
<span class="n">my_lambda</span><span class="p">.</span><span class="nf">lambda?</span>
</code></pre>
<p>The result is <code>false</code> but I would expect it to be <code>true</code></p>
<p>There is currently a way to turn a proc into a lambda in MRI like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">convert_to_lambda</span> <span class="o">&</span><span class="n">block</span>
<span class="n">obj</span> <span class="o">=</span> <span class="no">Object</span><span class="p">.</span><span class="nf">new</span>
<span class="n">obj</span><span class="p">.</span><span class="nf">define_singleton_method</span><span class="p">(</span><span class="ss">:_</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="k">return</span> <span class="n">obj</span><span class="p">.</span><span class="nf">method</span><span class="p">(</span><span class="ss">:_</span><span class="p">).</span><span class="nf">to_proc</span>
<span class="k">end</span>
</code></pre>
<p>But this feels like a hack, and is not supported across other implementations. I would expect that passing a proc into a lambda to return a lambda, I believe it is a bug.</p> Ruby master - Feature #7132 (Assigned): Alternation between named / ordered method arguments and ...https://bugs.ruby-lang.org/issues/71322012-10-09T21:17:44ZAnonymous
<p>=begin<br>
Hi everyone. I am using Ruby for >1 year and I would like to share with you my dreams regarding the named method arguments planned for 2.0. Let us imagine a class Thief with 3 properties (name, hit_points and dexterity), which has constructor #new_thief:</p>
<pre><code>new_thief name: "John Fingers", hit_points: 14, dexterity: 15
</code></pre>
<p>I dream about this constructor accepting alternative syntax:</p>
<pre><code>new_thief "John Fingers", hit_points: 14, dexterity: 15
</code></pre>
<p>and accepting synonyms (aliases) :hp for :hit_points and :dex for dexterity:</p>
<pre><code>new_thief "John Fingers", hp: 14, dex: 15
</code></pre>
<p>To explain my motivation, I am creating a DSL in biology. I am facing the challenge of explaining to my colleagues why is it better than their current Java app. Biologists love synonyms, and I'd like the users calling constructors for biological objects to have freedom to use the synonym they like. Of course, I can already achieve it in 1.9.3:</p>
<pre><code>def new_thief *args
oo = args.extract_options!
raise ArgumentError if args[0] and oo[:name] and args[0] != oo[:name]
name = args[0] || oo[:name] || "John Doe"
raise ArgumentError if oo[:hp] and oo[:hit_points] and oo[:hp] != oo[:hit_points]
hp = oo[:hp] || oo[:hit_points] || 9
raise ArgumentError if oo[:dex] and oo[:dexterity] and oo[:dex] != oo[:dexterity]
dex = oo[:dex] || oo[:dexterity] || 11
Thief.new( name: name, hit_points: hp, dexterity: dex )
end
</code></pre>
<p>But I find myself doing this over and over, and even if I write a library to make it easier, it's still too cumbersome.</p>
<p>Proposal no. 1: I propose that alternation between named / ordered arguments and aliases (synonyms) for named method arguments be catered for already by core syntax.</p>
<p>Proposal no. 2: I propose that the syntax for this be as follows:</p>
<pre><code>def new_thief( name=**:name="John Doe", hp: **:hit_points=14, dex: **:dexterity=15 )
Thief.new name: name, hit_points: hp, strength: str, dexterity: dex
end
</code></pre>
<p>where expressions **:arg_name would refer to the named argument :arg_name.</p>
<p>Please judge the two proposals independently. I really dream about having the alternation between named / ordered arguments and aliases for named arguments in Ruby 2.0. But I feel less sure that the syntax **:arg_name that I am proposing is the best possible syntax for this. Mind me, I don't think it is bad, I am just not sure it is <em>best</em>.</p>
<p>PS: Please forgive me suggesting such a complicated feature, while being unable to write a single line in C.<br>
=end</p> Ruby master - Feature #7121 (Assigned): Extending the use of `require'https://bugs.ruby-lang.org/issues/71212012-10-09T10:09:29Zmjones (Morgan Jones)integ3rs@gmail.com
<p>=begin<br>
I was playing with Ruby tonight and thought up an interesting idea to make (({require})) a bit better, so you can load multiple files sequentially using one method call.</p>
<p>Currently, (({require})) supports one argument, and throws a (({TypeError})) if you pass an array:</p>
<p>irb(main):001:0> require %w(json yaml)<br>
TypeError: can't convert Array into String</p>
<p>However, there's a way to patch Kernel that makes it respond to multiple objects passed in an (({Array})).</p>
<p>module Kernel<br>
@@require = method :require</p>
<p>def require *args<br>
args.flatten!<br>
args.collect! do |a|<br>
raise ArgumentError.new "arguments to `require' must be strings or symbols" unless a.is_a?(String) || a.is_a?(Symbol)<br>
@@require.call a.to_s<br>
end</p>
<pre><code> args.length == 1 ? args.first : args
</code></pre>
<p>end<br>
end</p>
<p>The new behavior doesn't actually require the modification of any code that calls (({require})) (pretty much anything, really), and new code can take advantage of the new functionality instantly.</p>
<p>irb> require %w(json yaml)<br>
=> [true, false]<br>
irb> require :pp<br>
=> false<br>
irb> require 'rails'<br>
=> true<br>
irb> require %w(json yaml), :pp, 'rails'<br>
=> [true, false, false, true]<br>
=end</p>
<p>Thanks for considering this.</p> Ruby master - Feature #7087 (Assigned): ::ConditionVariable#wait does not work with Monitor becau...https://bugs.ruby-lang.org/issues/70872012-09-30T00:19:32Zrklemme (Robert Klemme)shortcutter@googlemail.com
<p>See program attached to bug <a class="issue tracker-2 status-2 priority-4 priority-default" title="Feature: ConditionVariable#wait has meaningless return value (Assigned)" href="https://bugs.ruby-lang.org/issues/7086">#7086</a>: timeout_4 always throws:</p>
<p>ERROR: method "timeout_4": #<NoMethodError: private method `sleep' called for #<a href="Monitor:0x87e49f8" class="external">Monitor:0x87e49f8</a>></p>
<p>$ irb19 -r monitor<br>
irb(main):001:0> Monitor.new.method(:sleep)<br>
=> #<Method: Monitor(Kernel)#sleep><br>
irb(main):002:0> Monitor.instance_methods.grep /sleep/<br>
=> []</p> Ruby master - Feature #7086 (Assigned): ConditionVariable#wait has meaningless return valuehttps://bugs.ruby-lang.org/issues/70862012-09-30T00:14:11Zrklemme (Robert Klemme)shortcutter@googlemail.com
<p>I consider this an API bug: when invoked with a timeout value the caller cannot distinguish from the return value whether the condition has been signaled or the time has run out. Consider how Java does it: <a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html#await(long,%20java.util.concurrent.TimeUnit)" class="external">http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html#await(long,%20java.util.concurrent.TimeUnit)</a> and <a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html#awaitUntil(java.util.Date)" class="external">http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html#awaitUntil(java.util.Date)</a></p>
<p>There's another issue exhibited through the script but I will create a separate ticket for this.</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 #6842 (Assigned): Add Optional Arguments to String#striphttps://bugs.ruby-lang.org/issues/68422012-08-07T20:24:20Zwardrop (Tom Wardrop)tom@tomwardrop.com
<p>=begin<br>
One of the very few things I miss from the ol' php days many years ago, was the ability to easily strip arbitrary characters from the ends of string using trim(). Typically, this is whitespace characters, and #strip currently fulfils that use case, but there are also instances where it'd be nice to be able to strip any range of characters from the ends of a string. It goes well with Array#join as often when joining strings with a delimiter, you want to make sure those strings don't already begin or end with that character.</p>
<p>For a full-featured #strip, I'd like to see it have the option of accepting both an Array or String. If a string is provided, each character in that string will be stripped. If an array of strings is given, each element of the array is stripped from the ends of the string - this allows for multi-character delimiters for example. Of course you could go really nuts and supports regex as well (or instead of arrays). To demonstrate the difference...</p>
<pre><code>"<b>bold text</b>".strip("</b>") #=> "old text"
"<b>bold text</b>".strip(["<b>", "</b>"]) #=> "bold text"
"<em><b>bold text</b></em>".strip(["<b>", "</b>", "<em>", "</em>"]) #=> "bold text"
"<em><b>bold text</b></em>".strip(/<\/?.+?>/) #=> "bold text"
</code></pre>
<p>A simple real-world example; this is actually what I was wanting to do right before I came here to raise this feature request, but there's been all kinds of other use cases I've hit in the past:</p>
<pre><code>['some', '/chunked', 'path/'].map{ |v| v.strip('/') }.join('/') #=> "some/chunked/path"
</code></pre>
<p>File#join does something similar, but when you need control over the joining character, this is the way you'd do it.</p>
<p>I've lost count of how many times I've wanted this in Ruby, and there's really no nice workaround. Here's an example on StackOverflow of someone asking how to achieve this stripping behaviour in ruby: <a href="http://stackoverflow.com/questions/3453262/how-to-strip-leading-and-trailing-quote-from-string-in-ruby" class="external">http://stackoverflow.com/questions/3453262/how-to-strip-leading-and-trailing-quote-from-string-in-ruby</a></p>
<p>Obviously, you'd do the same for #lstrip and #rstrip, and all the mutable variants (#strip!, #lstrip!, #rstrip!). Looking forward to others thoughts on this one.<br>
=end</p> Ruby master - Feature #6811 (Assigned): File, Dir and FileUtils should have bang-versions of sing...https://bugs.ruby-lang.org/issues/68112012-07-29T20:34:08Zprijutme4ty (Ilya Vorontsov)prijutme4ty@gmail.com
<p>I found that often write<br>
Dir.mkdir(folder) unless Dir.exist? folder<br>
and similar code for rm, rm_rf and so on<br>
We can simply make bang-versions like<br>
def Dir.mkdir!(folder, permissions=0744)<br>
Dir.mkdir(folder, permissions) unless Dir.exist? folder</p>
<a name="or-another-alternative-Dirmkdirfolder-permissions-rescue-false"></a>
<h1 >or another alternative Dir.mkdir(folder, permissions) rescue false<a href="#or-another-alternative-Dirmkdirfolder-permissions-rescue-false" class="wiki-anchor">¶</a></h1>
<p>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 #6695 (Assigned): Configuration for Thread/Fiber creationhttps://bugs.ruby-lang.org/issues/66952012-07-04T14:24:28Zko1 (Koichi Sasada)
<p>=begin<br>
= Abstract</p>
<p>With Feature <a class="issue tracker-2 status-2 priority-4 priority-default" title="Feature: Thread.new without block. (Assigned)" href="https://bugs.ruby-lang.org/issues/6694">#6694</a>, the following configuration parameters should be allowed for Thread/Fiber creation.</p>
<p>Group1 (new parameters):</p>
<ul>
<li>name: Thread/Fiber name</li>
<li>vm_stack_size: VM's stack size</li>
<li>machine_stack_size: Machine stack size</li>
</ul>
<p>Group2 (existing parameters):</p>
<ul>
<li>local_storage: Initial Thread/Fiber local parameters</li>
<li>thread_group: Thread group (Thread only)</li>
<li>priority: Initial priority Thread#priority= (Thread only)</li>
<li>abort_on_exception: abort on exception (Thread only)</li>
</ul>
<p>= Background</p>
<p>With Feature <a class="issue tracker-2 status-2 priority-4 priority-default" title="Feature: Thread.new without block. (Assigned)" href="https://bugs.ruby-lang.org/issues/6694">#6694</a>, we have a way to specify configurations for Thread creation. Fiber.new() don't receive any parameters now.</p>
<p>= Proposal</p>
<p>This is a initial proposal of configuration for Thread/Fiber creation.</p>
<p>Group1 (new parameters):</p>
<ul>
<li>name: Thread/Fiber name</li>
<li>vm_stack_size: VM's stack size</li>
<li>machine_stack_size: Machine stack size</li>
</ul>
<p>vm_stack_size and machine_stack_size are OS dependent (This means that it will be <em>hint</em> parameter).</p>
<p>Thread#inspect should use `name' parameter.</p>
<p>I also propose a new method Thread#name to get the thread name specified by this parameter.</p>
<p>Group2 (existing parameters):</p>
<ul>
<li>local_storage: Initial Thread/Fiber local parameters</li>
<li>thread_group: Thread group (Thread only)</li>
<li>priority: Initial priority Thread#priority= (Thread only)</li>
<li>abort_on_exception: abort on exception (Thread only)</li>
</ul>
<p>Now, we can specify Group2 parameters only <em>after</em> thread creation. With this parameter, we can specify parameters before thread creation.</p>
<p>=end</p> Ruby master - Feature #6694 (Assigned): Thread.new without block.https://bugs.ruby-lang.org/issues/66942012-07-04T13:51:11Zko1 (Koichi Sasada)
<a name="Abstract"></a>
<h1 >Abstract<a href="#Abstract" class="wiki-anchor">¶</a></h1>
<p>Support Thread.new() without block.</p>
<p>Before: <code>Thread.new(params...){|thread_local_params| ...}</code></p>
<p>After: <code>Thread.new(proc: lambda{|tl_params...| ...}, args: params..., other_thread_config...)</code></p>
<a name="Background"></a>
<h1 >Background<a href="#Background" class="wiki-anchor">¶</a></h1>
<p>Thread.new creates new Thread object and run passed block in another thread immediately. Thread.new can receive parameters and pass all parameters to block.</p>
<pre><code> Thread.new(a, b, c) do |ta, tb, tc|
# ta, tb, tc is thread local
}
</code></pre>
<p>There are some request to specify thread configurations such as stack size described in [Ruby 1.9 - Feature <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Allow dynamic Fiber stack size (Rejected)" href="https://bugs.ruby-lang.org/issues/3187">#3187</a>] (in this case, stack size for Fiber.new). However, we have no way to pass such thread configuration on the Thread.new().</p>
<a name="Proposal"></a>
<h1 >Proposal<a href="#Proposal" class="wiki-anchor">¶</a></h1>
<p>Allow Thread.new() without block. A block will be passed with proc parameter. Passed arguments will be passed with args parameter.</p>
<pre><code> # ex1
Thread.new(){...}
#=>
Thread.new(proc: -> {...})
# ex2
Thread.new(a, b, c){|ta, tb, tc| ...}
#=>
Thread.new(proc: ->(ta, tb, tc){ ... }, params: [a, b, c])
</code></pre>
<p>If you want to specify stack size, then:</p>
<p>Thread.new(stack_size: 4096, proc: proc{...}, args: [a, b, c])</p>
<p>Note that I'll make another ticket for thread (and fiber) creation parameters.</p>
<p>This change can be described with the following pseudo code:</p>
<pre><code> def Thread.new(*args, &block)
if block
Thread.new_orig(*args, &block)
else
config = args[0] || raise ArgumentError
stack_size = config[:stack_size]
# ... and process another parameters
Thread.new_orig(*config[:args], &config[:proc])
end
end
</code></pre>
<a name="Another-proposal"></a>
<h1 >Another proposal<a href="#Another-proposal" class="wiki-anchor">¶</a></h1>
<p>On the <a href="/issues/3187">[ruby-core:43385]</a>, Nahi-san proposed that if no block given on Thread.new(), then create "waiting" thread. Thread#run kicks waiting thread with parameters.</p>
<pre><code> th = Thread.new(thread_config_params)
...
th.run(params){|thread_local_params|
...
}
</code></pre>
<p>We can combine with <code>proc:</code> parameter and this proposal.<br>
If <code>Thread.new()</code> doesn't have block and <code>proc:</code> parameter, then making a waiting thread.</p>
<p>NOTE: Because we have already Thread#run, Thread#start is better than Thread#run?</p>
<a name="Note"></a>
<h1 >Note<a href="#Note" class="wiki-anchor">¶</a></h1>
<p>I don't make any survey on other languages. Please give us your comments.</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 #6671 (Assigned): File.split_all and File.split_roothttps://bugs.ruby-lang.org/issues/66712012-06-30T04:28:57Ztrans (Thomas Sawyer)
<p>=begin<br>
Is there a method for this already?</p>
<p>File.split_all('a/b/c') #=> ['a','b','c']</p>
<p>If not I propose it be added. I've had need of such more than a few times.</p>
<p>It's too bad that File.split can't do this, as it would make more sense. And the current method be called <code>split_base</code>.</p>
<p>In addition <code>split_root</code> would be helpful.</p>
<p>root, path = File.split_all('a/b/c')<br>
root #=> 'a'<br>
path #=> 'b/c'<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 #6611 (Assigned): Comments requested on implementation of set_parse_funchttps://bugs.ruby-lang.org/issues/66112012-06-20T07:46:26Zcjheath (Clifford Heath)clifford.heath@gmail.com
<p>Folk,</p>
<p>I've implemented Twister, a new mutation testing tool to replace Heckle.<br>
It relies on a new hook into the Ruby parser, in order to modify what the<br>
parser thinks it has seen.</p>
<p>Although I have written C extensions before, there are some aspects of<br>
the Ruby core which I'm unfamiliar with and as a result don't know the right<br>
way to handle. I'd like your comments, suggestions and improvements<br>
please.</p>
<p><a href="https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db" class="external">https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db</a></p>
<p>In particular, I'd like to know the following:</p>
<ol>
<li>Do you prefer that I move the literal strings (which occur once each) to #defined?</li>
</ol>
<p><a href="https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L1R1003" class="external">https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L1R1003</a></p>
<ol start="2">
<li>Will this line of code mess up the GC, and how should I fix that?</li>
</ol>
<p><a href="https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L1R3853" class="external">https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L1R3853</a></p>
<ol start="3">
<li>The set_parse_func is extern though it should be static, but I need to move<br>
the rb_define_global_function out of thread.c. Can someone please tell me where I should<br>
move it to, since there is no Init_Parser?</li>
</ol>
<p><a href="https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L1R9029" class="external">https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L1R9029</a></p>
<p><a href="https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L3R4705" class="external">https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L3R4705</a></p>
<ol start="4">
<li>I think I should change set_parse_func to accept a flags argument and a block,<br>
instead of assuming all flags, and taking a Proc. What are the downsides of using a<br>
block instead of a Proc (does this reduce the number of Bindings that get created)?<br>
How do I change set_parse_func to use a block?</li>
</ol>
<p>The initial implementation of Twister is an extension to RSpec which adds the option<br>
"--twist file-or-dir". It's still a bit rough - it needs to change the reporting on the twisted<br>
runs that follow the first (untwisted) run - but it does prove then concept.</p>
<p>Clifford Heath, Data Constellation, <a href="http://dataconstellation.com" class="external">http://dataconstellation.com</a><br>
Agile Information Management and Design.</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 - Feature #6413 (Assigned): Make Dir.entries default to Dir.entries(Dir.pwd)https://bugs.ruby-lang.org/issues/64132012-05-08T22:12:34Zshevegen (Robert A. Heiler)shevegen@gmail.com
<p>Is there a reason why Dir.entries requires one argument?</p>
<p>I think it would be easier and more convenient for the userruby if it would default to the current directory. Like so:</p>
<p>Dir.entries(i = Dir.pwd)</p>
<p>Or is there a reason why this is not done?</p> Ruby master - Feature #6376 (Assigned): Feature lookup and checking if feature is loadedhttps://bugs.ruby-lang.org/issues/63762012-04-29T07:03:40Ztrans (Thomas Sawyer)
<p>$LOADED_FEATURES is useful to know what "files" have been loaded. But it doesn't really tell us what "features" have been loaded. If there where were a way to look-up a load path, without actually loading it then it would be possible to compare that to $LOADED_FEATURES and thus know. e.g.</p>
<pre><code>require 'ostruct'
$LOADED_FEATURES #=> [..., "/home/trans/.local/lib/ry/rubies/1.9.3-p125/lib/ruby/1.9.1/ostruct.rb"]
path = require_path('ostruct') #=> "/home/trans/.local/lib/ry/rubies/1.9.3-p125/lib/ruby/1.9.1/ostruct.rb"
$LOADED_FEATURES.include?(path)
</code></pre>
<p>Of course, it would be nice to also have:</p>
<pre><code>required?('ostruct') #=> true
</code></pre>
<p>These methods could be class methods of special module, if it's important to keep the Kernel more tidy, e.g. <code>Ruby.required?('ostruct')</code>.</p>
<p>I am currently working on a project where I need this (and have a couple of other projects that could use it too) and I've had to implement the whole thing from scratch, which isn't simple, nor fast, nor am I 100% confident that it specs exactly to Ruby's own lookup procedure. So it would be much better if Ruby would expose its lookup functionality.</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 #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 #6277 (Assigned): Hash#convert_keyhttps://bugs.ruby-lang.org/issues/62772012-04-11T01:12:20Ztrans (Thomas Sawyer)
<p>=begin<br>
Many times a hash with uniform keys is needed (or is at least preferable) for a particular usecase. To this end I propose ((%Hash#convert_key%)).</p>
<p>h = {}<br>
h.convert_key{ |k| k.to_sym }<br>
h['a'] = 1<br>
h.update('b'=>2)<br>
h #=> {:a=>1, :b=>2}</p>
<p>The idea is similar in concept to ((%#default_proc%)).</p>
<p>Others solutions to fill this need have been tried and used, but almost exclusively are in the form of a new class. Most notable is Rails HashWithIndifferentAccess. But ((%#convert_key%)) has much greater flexibility since keys can be converted to anything.<br>
=end</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 #5970 (Assigned): Add Enumerable#join with same semantics as Array#joinhttps://bugs.ruby-lang.org/issues/59702012-02-05T17:27:39Znow (Nikolai Weibull)now@disu.se
<p>Currently, to join the elements of an Enumerable, you need to call #to_a on the Enumerable and then #join the result. With Enumerable#join one wouldn’t need need to create an intermediate Array.</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 #5582 (Assigned): Allow clone of singleton methods on a BasicObjecthttps://bugs.ruby-lang.org/issues/55822011-11-07T12:34:13Zthinkerbot (Simon Chiang)simon.a.chiang@gmail.com
<p>Currently I do not know of a way to implement something like 'clone' on a BasicObject subclass. This is as close as I've gotten but as you can see the singleton methods are not propagated to the clone.</p>
<pre><code>require 'test/unit'
class Context < BasicObject
def _singleton_class_
class << self
SINGLETON_CLASS = self
def _singleton_class_
SINGLETON_CLASS
end
end
_singleton_class_
end
def _class_
_singleton_class_.superclass
end
def _extend_(mod)
mod.__send__(:extend_object, self)
end
def _initialize_clone_(orig)
# set variables as needed
end
def _clone_
clone = _class_.allocate
clone._initialize_clone_(self)
_singleton_class_.included_modules.each {|mod| clone._extend_ mod }
clone
end
end
class ContextTest < Test::Unit::TestCase
module A
def a
:a
end
end
def test__clone__inherits_modules
context = Context.new
context._extend_ A
clone = context._clone_
assert_equal :a, clone.a
end
def test__clone__inherits_singleton_methods
context = Context.new
def context.a
:a
end
clone = context._clone_
assert_equal :a, clone.a # fails
end
end
</code></pre>
<p>Is there a way to do this that I don't see? If not, then I request that a way be added - perhaps by allowing the singleton_class to be set somehow.</p>
<p>In my case I am using Context as the context for a dsl where methods write to a target (an instance variable). I want to be able to clone a context such that I can have multiple contexts with the same methods, including extensions and singletons, that write to different targets.</p>
<p>Thank you.</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 #5129 (Assigned): Create a core class "FileArray" and make "ARGF" its instancehttps://bugs.ruby-lang.org/issues/51292011-08-01T13:57:46Zyimutang (Joey Zhou)
<p>I suggest to create a class "<code>FileArray</code>" whose instance behaves just like <code>ARGF</code> do.<br>
And I think <code>ARGF</code> should be an instance of <code>FileArray</code>. Now when I "<code>p ARGF.class</code>", I get "<code>ARGF.class</code>", so <code>ARGF</code> is an instance of <code>ARGF.class</code>, how meaningless it is.</p>
<p>FileArray methods:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># create an instance</span>
<span class="n">fa</span> <span class="o">=</span> <span class="no">FileArray</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s1">'a.txt'</span><span class="p">,</span><span class="s1">'b.txt'</span><span class="p">,</span><span class="s1">'c.txt'</span><span class="p">)</span>
<span class="c1"># take many methods from IO</span>
<span class="c1"># most methods from ARGF should be instance methods of ARGF </span>
<span class="n">fa</span><span class="p">.</span><span class="nf">each</span> <span class="p">{</span><span class="o">|</span><span class="n">line</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">line</span> <span class="p">}</span>
<span class="n">fa</span><span class="p">.</span><span class="nf">realines</span>
<span class="n">fa</span><span class="p">.</span><span class="nf">filename</span> <span class="c1"># current file</span>
<span class="c1"># but "argv" not</span>
<span class="nb">p</span> <span class="n">fa</span><span class="p">.</span><span class="nf">file_list</span> <span class="c1"># in ARGF, its ARGF.argv, but #argv is not a proper name for FileArray</span>
<span class="c1"># ARGV array can be modified, adding new file into it, all replace to a new file list.</span>
<span class="c1"># FileArray should add some methods to modify the inner file list.</span>
<span class="n">fa</span><span class="p">.</span><span class="nf">insert</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="s2">"d.txt"</span><span class="p">)</span>
<span class="n">fa</span><span class="p">.</span><span class="nf">delete</span><span class="p">(</span><span class="s1">'a.txt'</span><span class="p">)</span>
</code></pre>
<p>With <code>FileArray</code>, You can create multiple <code>ARGF</code>-like file arrays simultaneously.</p>
<p>For example, I want to mix two <em>groups</em> of files, not two files:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a_files</span> <span class="o">=</span> <span class="no">FileArray</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="o">*</span><span class="no">Dir</span><span class="p">.</span><span class="nf">glob</span><span class="p">(</span><span class="s1">'a*.txt'</span><span class="p">))</span>
<span class="n">b_files</span> <span class="o">=</span> <span class="no">FileArray</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="o">*</span><span class="no">Dir</span><span class="p">.</span><span class="nf">glob</span><span class="p">(</span><span class="s1">'b*.txt'</span><span class="p">))</span>
<span class="n">enum_a</span> <span class="o">=</span> <span class="n">a_files</span><span class="p">.</span><span class="nf">each</span>
<span class="n">enum_b</span> <span class="o">=</span> <span class="n">b_files</span><span class="p">.</span><span class="nf">each</span>
<span class="kp">loop</span> <span class="k">do</span>
<span class="nb">puts</span> <span class="n">enum_a</span><span class="p">.</span><span class="nf">next</span>
<span class="nb">puts</span> <span class="n">enum_b</span><span class="p">.</span><span class="nf">next</span>
<span class="k">end</span>
</code></pre> Ruby master - Feature #5064 (Assigned): HTTP user-agent classhttps://bugs.ruby-lang.org/issues/50642011-07-21T13:10:00Zdrbrain (Eric Hodel)drbrain@segment7.net
<p>Currently there are some problems with Net::HTTP:</p>
<ul>
<li>Too many ways to use (user confusion)</li>
<li>No automatic support for HTTPS (must conditionally set use_ssl)</li>
<li>No automatic support for HTTPS peer verification (must be manually set)</li>
<li>Single-connection oriented</li>
<li>No support for redirect-following</li>
<li>No support for HTTP/1.1 persistent connection retry (RFC 2616 8.1.4)</li>
<li>No automatic support for HTTP proxies</li>
<li>No automatic support for authentication (must be set per-request)</li>
</ul>
<p>Additionally the style of the API of Net::HTTP makes it difficult to take advantage of persistent connections. The user has to store the created connection and manually handle restarting the connection if it has timed out or is closed by the server.</p>
<p>RFC 2616 8.1.1 has a large section explaining the benefits of persistent connections, but while Net::HTTP implements persistent connections they could be easier for users to implement with next work.</p>
<p>I've implemented support for many of these additional features of Net::HTTP in various projects and I'd like Ruby to have the features required to make a useful HTTP user-agent built-in.</p>
<p>The agent should have the following responsibilities:</p>
<ul>
<li>Make or reuse connections based on [host, port, SSL enabled]</li>
<li>Automatically enable SSL for https URIs</li>
<li>Automatically enable SSL peer verification for SSL connections</li>
<li>Limit number of persistent connections per host</li>
<li>Follow redirects</li>
<li>Retry when a persistent connection fails</li>
<li>Automatically configure proxies</li>
<li>Automatically use authentication</li>
<li>Callbacks for various options connect</li>
</ul>
<p>The agent may add the following responsibilities:</p>
<ul>
<li>Default headers for all requests</li>
<li>HTTP cookies</li>
<li>Tracking history</li>
<li>Logging</li>
</ul>
<p>I don't think any of these features are critical as they are implementable by users via callbacks.</p>
<p>The agent would have the following configurable items:</p>
<ul>
<li>Number of connections per host</li>
<li>Depth of redirects followed</li>
<li>Persistent connection retries (none, HTTP/1.1 (default), always)</li>
<li>Proxy host, port, user, password</li>
</ul>
<p>I think the class should be called Net::HTTP::Agent.</p>
<p>Basic use would look something like this:</p>
<p>uris = [<br>
URI('http://example/1'),<br>
URI('http://example/2'),<br>
URI('https://secure.example'),<br>
]</p>
<p>agent = Net::HTTP::Agent.new</p>
<p>uris.map do |uri|<br>
agent.get uri # Returns Net::HTTPResponse<br>
end</p>
<p>For special requests a Net::HTTPRequest could be constructed:</p>
<p>req = Net::HTTP::Get.new uri.request_uri</p>
<a name="do-something-special-with-req"></a>
<h1 >do something special with req<a href="#do-something-special-with-req" class="wiki-anchor">¶</a></h1>
<p>agent.request req</p>
<p>The agent should support GET, POST, etc. directly through API methods. I think the API should look something like this:</p>
<p>def get uri_or_string, query = nil, headers = nil</p>
<a name="Same-for-other-requests-with-no-body"></a>
<h1 >Same for other requests with no body<a href="#Same-for-other-requests-with-no-body" class="wiki-anchor">¶</a></h1>
<h1></h1>
<a name="query-may-be-a-Hash-or-String"></a>
<h1 >query may be a Hash or String<a href="#query-may-be-a-Hash-or-String" class="wiki-anchor">¶</a></h1>
<a name="How-query-param-vs-query-string-in-URI-is-used-is-undecided"></a>
<h1 >How query param vs query string in URI is used is undecided<a href="#How-query-param-vs-query-string-in-URI-is-used-is-undecided" class="wiki-anchor">¶</a></h1>
<p>def post uri_or_string, data, headers = nil</p>
<a name="same-for-other-requests-with-a-body"></a>
<h1 >same for other requests with a body<a href="#same-for-other-requests-with-a-body" class="wiki-anchor">¶</a></h1>
<h1></h1>
<a name="data-may-be-a-String-IO-or-Hash"></a>
<h1 >data may be a String, IO or Hash<a href="#data-may-be-a-String-IO-or-Hash" class="wiki-anchor">¶</a></h1>
<a name="How-data-format-is-chosen-is-undecided"></a>
<h1 >How data format is chosen is undecided<a href="#How-data-format-is-chosen-is-undecided" class="wiki-anchor">¶</a></h1>
<p>SSL options, proxy options, timeouts and similar options should exist on Net::HTTP::Agent and be set on new connections as they are made.</p>
<p>I've implemented most of these features in mechanize as Mechanize::HTTP::Agent. The Agent class in mechanize is bigger than is necessary and would need to be cut-down for inclusion in Ruby as Net::HTTP::Agent</p>
<p><a href="https://github.com/tenderlove/mechanize/blob/master/lib/mechanize/http/agent.rb" class="external">https://github.com/tenderlove/mechanize/blob/master/lib/mechanize/http/agent.rb</a></p>
<p>Mechanize depends on net-http-persistent to provide HTTP/1.1 retry support and connection management:</p>
<p><a href="https://github.com/drbrain/net-http-persistent/blob/master/lib/net/http/persistent.rb" class="external">https://github.com/drbrain/net-http-persistent/blob/master/lib/net/http/persistent.rb</a></p>
<p>Portions of net-http-persistent should be patches of Net::HTTP, for example #idempotent? #can_retry?, #reset and portions of #request. Other parts (connection management) should be moved to Net::HTTP::Agent.</p>
<p>net-http-persistent provides a separate connection list per thread. I would like Net::HTTP::Agent to be multi-thread friendly but implementing this in another way would be fine.</p>
<p>As an addendum, open-uri and mechanize should be written to take advantage of Net::HTTP::Agent on order to guide useful implementation.</p> 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 #4818 (Assigned): Add method marshalable?https://bugs.ruby-lang.org/issues/48182011-06-03T11:07:15Zyimutang (Joey Zhou)
<p>Some objects can not be marshaled. Maybe there should be a method to tell it.</p>
<p>hash = Hash.new {|h,k| k * 2}</p>
<p>this hash can't be marshaled because it has a default proc. If existing such method:</p>
<p>Marshal.marshalable?(hash) #=> method "Marshal.marshalable?"<br>
hash.marshalable? #=> method "Kernel#marshalable?"</p>
<p>If you think the method name hard to spell, maybe get a synonym "dumpable?"</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 #4514 (Assigned): #deep_clone and #deep_dup for Objectshttps://bugs.ruby-lang.org/issues/45142011-03-21T19:23:02Zwardrop (Tom Wardrop)tom@tomwardrop.com
<p>=begin<br>
There's often a need to do a deep clone of an object, especially of Hash/Array trees. The typical work around to the lack of this functionality is to Marshall and then Unmarshall (e.g. Marshal::load(Marshal::dump(self)) ), which incurs more overhead than it probably should, and is not very semantic. My suggestion is to either provide #deep_clone and #deep_dup methods on the Object class, or to at least provide equivalent functionality for Hashes and Arrays, such as possibly a #deep_merge method for Hash. The exact implantation is not a large concern of mine; I'll let the experts determine the best method of achieving the desired outcome.<br>
=end</p> Ruby master - Feature #4464 (Assigned): [PATCH] add Fcntl::Flock object for easier use of POSIX f...https://bugs.ruby-lang.org/issues/44642011-03-04T04:42:38Znormalperson (Eric Wong)normalperson@yhbt.net
<p>=begin<br>
This is a subclass of String so it is compatible with<br>
IO#fcntl without needing to modify io.c for systems<br>
that don't have POSIX file locks.<br>
=end</p> Ruby master - Feature #3953 (Assigned): TCPSocket / UDPSocket do not accept IPAddr objects.https://bugs.ruby-lang.org/issues/39532010-10-16T20:41:59Zpostmodern (Hal Brodigan)postmodern.mod3@gmail.com
<p>=begin<br>
I noticed that TCPSocket/UDPSocket only accept String IPs/Hostnames, but not IPAddr objects. This is counter-intuitive since IP Addresses, along with Hostnames, are used to connect/bind to sockets.</p>
<pre><code> require 'socket'
require 'resolv'
ip = IPAddr.new(Resolv.getaddress('www.example.com'))
sock = TCPSocket.new(ip,80)
TypeError: can't convert IPAddr into String
from (irb):5:in `initialize'
from (irb):5:in `new'
from (irb):5
</code></pre>
<p>=end</p> Ruby master - Feature #3608 (Assigned): Enhancing Pathname#each_child to be lazyhttps://bugs.ruby-lang.org/issues/36082010-07-24T10:27:14Ztaw (Tomasz Wegrzanowski)Tomasz.Wegrzanowski@gmail.com
<p>=begin<br>
Right now it lists entire directory, then yields<br>
every element, that is x.each_child(&b) means x.children.each(&b).</p>
<p>This is too slow for directories mounted over networked file systems etc.,<br>
and there is currently no way to get lazy behaviour, other than leaving<br>
convenient #each_child/#children API and moving to lower level.</p>
<p>With this patch:</p>
<ul>
<li>#children is eager like before, no change here</li>
<li>#each_child becomes lazy</li>
<li>#each_child without block returns lazy enumerator,<br>
so it can be used like this dir.each_child.find(&:symlink?)<br>
without losing laziness.</li>
</ul>
<p>Patch is against trunk. pathname.rb was in lib/ not ext/pathname/lib/<br>
before, but it works either way.</p>
<p>The part to return enumerator when called without a block wouldn't<br>
work in 1.8. If backport is desired, that line would need to be thrown<br>
away, and #children would need to build result array instead<br>
of calling each_child(with_directory).to_a - this would be straightforward.<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> Ruby master - Feature #2294 (Assigned): [PATCH] ruby_bind_stack() to embed Ruby in coroutinehttps://bugs.ruby-lang.org/issues/22942009-10-28T02:02:58Zsunaku (Suraj Kurapati)sunaku@gmail.com
<p>=begin<br>
Hi,</p>
<p>I am attaching a "ruby_bind_stack.patch" patch file<br>
that adds a ruby_bind_stack() function to the Ruby C API.</p>
<p>This function allows me to inform the GC about the stack<br>
boundaries of the coroutine inside which Ruby is embedded:</p>
<p>void ruby_bind_stack(void *lower, void *upper);</p>
<p>I am also attaching tarballs containing code examples that<br>
embed Ruby inside two different coroutine environments:<br>
UNIX System V contexts<a href="http://www.gnu.org/s/libc/manual/html_node/System-V-contexts.html" class="external">1</a> and libpcl<a href="http://www.xmailserver.org/libpcl.html" class="external">2</a> coroutines.</p>
<p>Each tarball has an "output.log" file which contains the<br>
result of running <code>script -c ./run.sh output.log</code> on my<br>
machine:</p>
<p>Linux yantram 2.6.31-ARCH #1 SMP PREEMPT Tue Oct 13 13:36:23 CEST 2009 i686 Intel(R) Pentium(R) D CPU 3.00GHz GenuineIntel GNU/Linux</p>
<p>The last section in "output.log" corresponds to Ruby @ SVN<br>
trunk that is patched with the "ruby_bind_stack.patch"<br>
patch file that is attached to this issue.</p>
<p>Thanks for your consideration.</p>
<p>See also:</p>
<ul>
<li><a href="http://redmine.ruby-lang.org/issues/show/2258" class="external">http://redmine.ruby-lang.org/issues/show/2258</a></li>
<li>
<a href="http://redmine.ruby-lang.org/issues/show/2126" class="external">http://redmine.ruby-lang.org/issues/show/2126</a><br>
=end</li>
</ul>