Ruby Issue Tracking System: Issueshttps://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17097754782024-03-14T10:17:44ZRuby Issue Tracking System
Redmine Ruby master - Misc #20336 (Open): DevMeeting-2024-04-17https://bugs.ruby-lang.org/issues/203362024-03-14T10:17:44Zmame (Yusuke Endoh)mame@ruby-lang.org
<a name="The-next-dev-meeting"></a>
<h1 >The next dev meeting<a href="#The-next-dev-meeting" class="wiki-anchor">¶</a></h1>
<p><strong>Date: 2024/04/17 13:00-17:00</strong> (JST)<br>
Log: <em>TBD</em></p>
<ul>
<li>Dev meeting <em>IS NOT</em> a decision-making place. All decisions should be done at the bug tracker.</li>
<li>Dev meeting is a place we can ask Matz, nobu, nurse and other developers directly.</li>
<li>Matz is a very busy person. Take this opportunity to ask him. If you can not attend, other attendees can ask instead of you (if attendees can understand your issue).</li>
<li>We will write a record of the discussion in the file or to each ticket in English.</li>
<li>All activities are best-effort (keep in mind that most of us are volunteer developers).</li>
<li>The date, time and place of the meeting are scheduled according to when/where we can reserve Matz's time.</li>
<li>
<em>DO NOT</em> discuss then on this ticket, please.</li>
</ul>
<a name="Call-for-agenda-items"></a>
<h1 >Call for agenda items<a href="#Call-for-agenda-items" class="wiki-anchor">¶</a></h1>
<p>If you have a ticket that you want matz and committers to discuss, please post it into this ticket in the following format:</p>
<pre><code>* [Ticket ref] Ticket title (your name)
* Comment (A summary of the ticket, why you put this ticket here, what point should be discussed, etc.)
</code></pre>
<p>Example:</p>
<pre><code>* [Feature #14609] `Kernel#p` without args shows the receiver (ko1)
* I feel this feature is very useful and some people say :+1: so let discuss this feature.
</code></pre>
<ul>
<li>It is recommended to add a comment by 2024/04/14. We hold a preparatory meeting to create an agenda a few days before the dev-meeting.</li>
<li>The format is strict. We'll use <a href="https://gist.github.com/mame/b0390509ce1491b43610b9ebb665eb86" class="external">this script to automatically create an markdown-style agenda</a>. We may ignore a comment that does not follow the format.</li>
<li>Your comment is mandatory. We cannot read all discussion of the ticket in a limited time. We appreciate it if you could write a short summary and update from a previous discussion.</li>
</ul> Ruby master - Misc #20320 (Open): Using OSU Open Source Lab native ppc64le/s390x CI services trig...https://bugs.ruby-lang.org/issues/203202024-03-01T16:26:28Zjaruga (Jun Aruga)
<p>We have been using Travis CI to run unit tests the native arm64/ppc64le/s390x in the ruby/ruby, ruby/zlib and ruby/prism repositories in the Ruby project.</p>
<p>One of the challenges is Travis CI's chronic unstable infra issues. To be fair, folks at Travis CI support are helpful, usually responding quickly, sometimes not. And I hope Travis CI will find the root causes of the issues. However, I would like to find alternative way to run the native ppc64le/s390x pipelines on pull-requests to change the current challenge fundamentally.</p>
<p>And I heard from folks at IBM that the there were CI services that we could run on the pull-requests. The CI services are Jenkins services provided by Oregon State University (OSU) Open Source Lab below. The CI services are the only alternative of running the native ppc64le/s390x pipelines on pull-requests as far as I know. As a note, we are already using SSH-accessing servers provided by OSU Open Source Lab.</p>
<ul>
<li>PowerPC64 (ppc64le): <a href="https://osuosl.org/services/powerdev/" class="external">https://osuosl.org/services/powerdev/</a> - POWER Continuous Integration (POWER CI)</li>
<li>IBM Z (s390x): <a href="https://osuosl.org/services/ibm-z/" class="external">https://osuosl.org/services/ibm-z/</a> - IBM Z Continuous Integration (IBM Z CI)</li>
</ul>
<p>Today I requested the CI services from the request form pages above. And I will try the services by myself first. Then if it looks good to us, I want to migrate the Travis CI ppc64le/s390x pipelines to the OSU Open Source Lab's ones. I will comment on this ticket when there are updates.</p>
<p>Note:<br>
Oregon State University Open Source Lab (OSUOSL) support email: <a href="mailto:support@osuosl.org" class="email">support@osuosl.org</a> and <a href="https://osuosl.org/contact/" class="external">other contacts</a>.</p> Ruby master - Misc #20287 (Open): DevMeeting before or after RubyKaigihttps://bugs.ruby-lang.org/issues/202872024-02-21T08:29:56Zduerst (Martin Dürst)duerst@it.aoyama.ac.jp
<p>RubyKaigi itself runs from May 15-17 (Wed-Fri) in Naha.</p>
<p>It would be nice to have a DevMeeting before or afterwards. We should try to plan ahead, so that people can make the right flight and hotel reservations early.</p>
<p>I have never been to Okinawa before and don't know any facilities that would be available.</p> Ruby master - Misc #20279 (Open): Is the implementation of `respond_to_missing?` in BasicObject d...https://bugs.ruby-lang.org/issues/202792024-02-19T05:18:57Zioquatix (Samuel Williams)samuel@oriontransfer.net
<p>Considering the documentation here: <a href="https://ruby-doc.org/3.2.2/BasicObject.html" class="external">https://ruby-doc.org/3.2.2/BasicObject.html</a></p>
<p>Introduced in: <a href="https://github.com/ruby/ruby/commit/3eb7d2b33e3f8555d81db5369eb6fb7100a91e63" class="external">https://github.com/ruby/ruby/commit/3eb7d2b33e3f8555d81db5369eb6fb7100a91e63</a></p>
<p>I wondered if <code>or super</code> is correct in <code>respond_to_missing?</code>.</p>
<p>For example:</p>
<pre><code>irb(main):001* class MyObjectSystem < BasicObject
irb(main):002* DELEGATE = [:puts, :p]
irb(main):003*
irb(main):004* def method_missing(name, *args, &block)
irb(main):005* return super unless DELEGATE.include? name
irb(main):006* ::Kernel.send(name, *args, &block)
irb(main):007* end
irb(main):008*
irb(main):009* public def respond_to_missing?(name, include_private = false)
irb(main):010* DELEGATE.include?(name) or super
irb(main):011* end
irb(main):012> end
=> :respond_to_missing?
irb(main):013> MyObjectSystem.new.respond_to_missing?(:foo)
(irb):5:in `method_missing': super: no superclass method `respond_to_missing?' for an instance of MyObjectSystem (NoMethodError)
from (irb):10:in `respond_to_missing?'
from (irb):13:in `<main>'
from <internal:kernel>:187:in `loop'
from /home/samuel/.gem/ruby/3.3.0/gems/irb-1.11.2/exe/irb:9:in `<top (required)>'
from /home/samuel/.gem/ruby/3.3.0/bin/irb:25:in `load'
from /home/samuel/.gem/ruby/3.3.0/bin/irb:25:in `<main>'
</code></pre>
<p>It looks wrong to me.</p>
<p>In addition, I'd like to know in what situations <code>BasicObject</code> should define <code>respond_to_missing?</code> - because I was under the impression it was called by <code>method_missing</code>. Does <code>BasicObject#method_missing</code> have this behaviour? Maybe we can improve the documentation cc <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/52355">@burdettelamar (Burdette Lamar)</a></p> Ruby master - Misc #20272 (Open): Ambiguity around Ractor message sending FIFO semanticshttps://bugs.ruby-lang.org/issues/202722024-02-16T18:26:09Zforthoney (Seong-Heon Jung)castlehoneyjung@gmail.com
<p>The docs should explicitly state the semantics/properties of Ractor message, especially when it comes to FIFO.<br>
For example, assume I have two Ractors, Ractor A and Ractor B. Ractor A sends two messages <code>"hello"</code> and <code>"world"</code> in this order to Ractor B.<br>
If I call <code>Ractor.receive</code> on Ractor B, am I guaranteed to see <code>"hello"</code> and then <code>"world"</code> or is it possible the messages are delivered out of order?</p> Ruby master - Misc #20259 (Open): Proposal to add "ruby --irb" and / or "ruby --start-irb" to sta...https://bugs.ruby-lang.org/issues/202592024-02-12T18:48:24ZrubyFeedback (robert heiler)
<p>This issue proposes to add:</p>
<p>a) a commandline flag to bin/ruby that allows the user to start irb,</p>
<p>and</p>
<p>b) allow the user to make use of ruby to start irb, via the commandline (thus, the<br>
proposal's a) and b) are naturally connected to one another, meaning that we would<br>
have a commandline flag for the binary "ruby", and this flag, when invoked, will<br>
start irb, in the current terminal, just as if we would have typed "irb")</p>
<p>Background to this proposal, including prior proposals:</p>
<p>I believe there are prior proposals that are related, such as this one here from<br>
~3 years ago:</p>
<p><a href="https://bugs.ruby-lang.org/issues/17859" class="external">https://bugs.ruby-lang.org/issues/17859</a></p>
<p>by deivid.</p>
<p>Note that my proposal is a bit different: I don't propose that "ruby" would behave<br>
like python here, but instead I would propose that bin/ruby gets a specific flag<br>
such as "--irb" and/or "--start-irb" (the latter is a bit longer to type, so the<br>
former is more convenient, but I also like that the latter, aka --start-irb is more<br>
specific, showing the intent more clearly; and we can add both flags anyway, so<br>
people can just pick what they prefer. I would probably just make an alias such<br>
as "rirb" for "ruby --start-irb" on my local system).</p>
<p>The way I came yesterday to a somewhat similar conclusion as deivid did, shall be<br>
explained next, even though my path is an indirect one.</p>
<p>As some may know, Tim (and others) are creating natalie, a ruby "dialect" (well,<br>
it'll be ruby in the end I believe but right now it does not satisfy the full<br>
ruby specification):</p>
<p><a href="https://github.com/natalie-lang/natalie" class="external">https://github.com/natalie-lang/natalie</a></p>
<p>Although there are some issues natalie currently has (it's a bit slow right now, for<br>
instance), they did invest quite a lot of time into it and it is slowly shaping up -<br>
at the least presently. More work to be done on satisfying ruby's specification.</p>
<p>Yesterday I compiled natalie from a git checkout and it compiled and installed fine.<br>
I was confused that under bin/ there was only "natalie", but no irb. I may be wrong<br>
but I think in the past I had bin/irb there too. Anyway, that then got me thinking<br>
that I may have made a mistake - but, also, why can't we just use ruby to start<br>
irb, as-is? That is, the executable called "ruby", under bin/ruby.</p>
<p>Yes, this is natalie, not ruby, I understand that. I also fully understand that MRI<br>
ruby having --irb and --start-irb does not change the situation for natalie, jruby,<br>
truffleruby - you name it. I get that, although I should like to point out that they<br>
may often follow suit what MRI ruby decides, so if they have a variant of irb, it<br>
may be likely that they would add the same or similar commandline flags to support<br>
changes in MRI, even if it may take a while (see jruby issue tracker having tons<br>
of todo-entries on github, to keep track of new ruby releases and what changed<br>
between version).</p>
<p>But I was then also wondering why ruby itself would not allow us to start irb in such<br>
a way, via "ruby". I understand that we have bin/irb, so this is not a real problem -<br>
people can just start "irb" normally. And I think we can require irb from a ruby .rb<br>
file just fine, as well, and use irb that way, all fine too. But even then I still<br>
wondered why we can not run irb via "ruby". Is there any reason that speaks against<br>
"ruby --start-irb" starting irb? I don't think the stdlib idea for ruby was to prevent<br>
ruby itself from providing convenience to the user. I also don't propose other gems<br>
to be started like that either, supporting many different commandline flags or<br>
--start=name_of_gem_here; irb is more important, in my opinion, than many other<br>
gems. The key idea for irb is to have "interactive ruby". pry pushed that idea<br>
further, and I think the recent irb releases included some ideas from pry too. ALL<br>
of these focus on an "interactive ruby", no matter the real name (be it irb,<br>
pry or anything else) - just as "python" without arguments focuses on "interactive<br>
python".</p>
<p>If we look at python, python kind of provides two ways to run things: "python foobar.py",<br>
and without argument, the interactive python. Again, I am not proposing to join that<br>
together, different to deivid's proposal, but indeed, it made me question ruby's current<br>
behaviour.</p>
<p>I think python's behaviour to be able to select either way, via "python" itself, is better;<br>
that we are unable to select which behaviour to use via commandline flag, in python, is a<br>
drawback, as jeremy pointed out since he prefers the current ruby heaviour, but via an<br>
additional commandline flag I think we can at the least get python's interactive behaviour<br>
into ruby (that is, IRB; although it should be mentioned that the new IRB is a bit different<br>
to the older IRB, but I leave it at that, since the proposal here is about starting IRB,<br>
not about IRB's behaviour - the latter is for the github project of IRB, rather than MRI's<br>
issue tracker here).</p>
<p>deivid reasoned that python's behaviour is useful for newbies, which I do not doubt. jeremy<br>
said that he prefers the current behaviour of ruby, which is also fine. An explicit commandline<br>
flag for starting irb may be a compromise, but I should like to say that my rationale today<br>
was different from deivid's one, in that I actually really want bin/ruby to give us a SIMPLE<br>
means to start irb, rather than merely "ruby" showing the same behaviour as "python" does,<br>
in regarsd to starting its interactive variant.</p>
<p>Again, I can work around this just fine, using a .rb file to start IRB and so forth, but I<br>
really think having this supported via a simple commandline flag may be more convenient. Of<br>
course, a secondary proposal to this may then be to add another commandline flag to get<br>
to support deivid's suggestion :) - but that would also be for another issue request on the<br>
bugtracker here. For this proposal, I really merely suggest to add --irb and/or --start-irb<br>
(or any other variant that may be more fitting, perhaps --interactive; the name is not so<br>
important, although it should be a convenient name and ideally short. The functionality is<br>
more important than the name.)</p>
<p>Implementation details:</p>
<p>Let's for a moment assume people may find this useful. Then the question is, which irb should<br>
be started when using "ruby --irb"?</p>
<p>Probably the most sensible default option here is to simply use whatever irb version has been<br>
installed on the target computer. Hiroshi Shibata and others worked towards gemifying ruby's<br>
stdlib, so it makes sense that "ruby --start-irb" would use the currently installed irb version,<br>
whatever that is. For most ruby users this is probably the one that came distributed with<br>
whatever ruby version they are using, at the least for modern ruby versions.</p>
<p>Otherwise they may just install a new irb version from e. g.</p>
<pre><code>https://github.com/ruby/irb
</code></pre>
<p>or whatever:</p>
<pre><code>gem install irb
</code></pre>
<p>installs. And this is then started when they do "ruby --start-irb". So, "ruby --start-irb"<br>
would be exactly the same as the user typing "irb" on the commandline, without any further<br>
arguments.</p>
<p>Of course the user can also start irb via "irb", as-is. So they'd only get an additional<br>
way to start irb. They can continue to use "irb" just fine. All that would change is that<br>
"ruby" itself would get an additional commandline argument, one that starts its "interactive<br>
part".</p>
<p>Anyway - I have no idea how much support the above would find; perhaps if jeremy is active<br>
he could compare it towards deivid's suggestion and comment on it too. I thought about<br>
appending to deivid's suggestion, but the suggestion here is a bit different, so I think<br>
it may be better to propose it as a separate one, even though it is somewhat close to his<br>
proposal, even though it is unrelated (see how I reached that conclusion, which I think is<br>
different than deivid's proposal).</p>
<p>I am not sure if there are even older proposals or not, but there may be. It's also fine<br>
to close this issue here, by the way, to keep the issue tracker list shorter (and perhaps<br>
link it towards deivid's above issue too, if this is closed, which is fine). I kind of<br>
wanted to contribute a bit to the discussion from a different point of view. Perhaps to<br>
avoid having too many open issues, this issue here could be left open for a month or<br>
two, to allow for a bit of more discussion, then it can be closed and e. g. referred to<br>
deivids' issue; and if deivid has time he may comment on the one here or his older<br>
proposal. At any rate, thank you for reading this proposal.</p>
<p>(PS: I filed it under Misc because it did not seem to necessarily be a Feature of the<br>
ruby language itself. Of course it could also fit under Feature, so I was not sure<br>
where to categorize it.)</p> Ruby master - Misc #20240 (Open): Unable to build ruby 3.1.0 on macOS when shared due to dylibs (...https://bugs.ruby-lang.org/issues/202402024-02-06T10:53:26Zjmarrec (Julien Marrec)
<p>I am trying to develop a conan (the C/C++ package manager) recipe for Ruby. The recipe would allow downstream users to 1) get a runnable ruby executable, and 2) be able to link to ruby, or embbed it in a C/C++ program if built statically, in an easy way.</p>
<p>Currently there is an existing ruby 3.1.0 recipe that I'm trying to adapt, so I have to support this version.</p>
<p>First off, let me say that I can succesfully build with 3.3.0, so I know something has changed for the better since then. I'm just at a lost when figuring out what I need to backport to make 3.1.0 work.</p>
<p>The original issue is that it appears miniruby is looking for some dylibs and not finding them. Even if I do define <code>LD_LIBRARY_PATH</code>, <code>DYLD_LIBRARY_PATH</code> or <code>DYLD_FALLBACK_LIBRARY_PATH</code> (any combinations of these three) in my env.</p>
<pre><code class="shell syntaxhl" data-language="shell">dsymutil exe/ruby<span class="p">;</span> <span class="o">{</span> <span class="nb">test</span> <span class="nt">-z</span> <span class="s1">''</span> <span class="o">||</span> codesign <span class="nt">-s</span> <span class="s1">''</span> <span class="nt">-f</span> exe/ruby<span class="p">;</span> <span class="o">}</span>
./miniruby <span class="se">\</span>
<span class="nt">-e</span> <span class="s1">'prog, dest, inst = ARGV; dest += "/ruby"'</span> <span class="se">\</span>
<span class="nt">-e</span> <span class="s1">'exit unless prog==inst'</span> <span class="se">\</span>
<span class="nt">-e</span> <span class="s1">'unless prog=="ruby"'</span> <span class="se">\</span>
<span class="nt">-e</span> <span class="s1">' begin File.unlink(dest); rescue Errno::ENOENT; end'</span> <span class="se">\</span>
<span class="nt">-e</span> <span class="s1">' File.symlink(prog, dest)'</span> <span class="se">\</span>
<span class="nt">-e</span> <span class="s1">'end'</span> <span class="se">\</span>
ruby exe ruby
dyld[59344]: Library not loaded: @rpath/libgmp.10.dylib
Referenced from: <356E0011-6223-321A-9179-D55618D248D0> /Users/julien/.conan2/p/b/ruby9cafa28a7060d/b/build-release/miniruby
Reason: no LC_RPATH<span class="s1">'s found
make: *** [exe/ruby] Abort trap: 6
make: *** Deleting file `exe/ruby'</span>
</code></pre>
<p>It seems that something is unsetting the variables, because this for eg works fine</p>
<pre><code class="shell syntaxhl" data-language="shell"><span class="nv">DYLD_LIBRARY_PATH</span><span class="o">=</span>/Users/julien/.conan2/p/b/zlib1f8e7d96319f0/p/lib:/Users/julien/.conan2/p/b/opense854e464e8ff6/p/lib:/Users/julien/.conan2/p/b/libyae2f0aa15c9e92/p/lib:/Users/julien/.conan2/p/b/libff05fe9d5b96f79/p/lib:/Users/julien/.conan2/p/b/readl0d0041a63fa03/p/lib:/Users/julien/.conan2/p/b/termc22b5bb1515971/p/lib:/Users/julien/.conan2/p/b/gmp676fa41eaa3d6/p/lib: /Users/julien/.conan2/p/b/ruby9cafa28a7060d/b/build-release/miniruby <span class="nt">-e</span> <span class="s2">"puts 'Hello, world'"</span>
</code></pre>
<p>My configure call is like this:</p>
<pre><code class="shell syntaxhl" data-language="shell">./configure <span class="nt">--enable-shared</span> <span class="nt">--disable-static</span> <span class="nt">--prefix</span><span class="o">=</span>/ <span class="s1">'--bindir=${prefix}/bin'</span> <span class="s1">'--sbindir=${prefix}/bin'</span> <span class="s1">'--libdir=${prefix}/lib'</span> <span class="s1">'--includedir=${prefix}/include'</span> <span class="s1">'--oldincludedir=${prefix}/include'</span> <span class="nt">--disable-install-doc</span> <span class="nt">--enable-load-relative</span> <span class="nt">--with-zlib-dir</span><span class="o">=</span>/Users/julien/.conan2/p/b/zlib1f8e7d96319f0/p <span class="nt">--with-openssl-dir</span><span class="o">=</span>/Users/julien/.conan2/p/b/opense854e464e8ff6/p <span class="nt">--with-libffi-dir</span><span class="o">=</span>/Users/julien/.conan2/p/b/libff05fe9d5b96f79/p <span class="nt">--with-libyaml-dir</span><span class="o">=</span>/Users/julien/.conan2/p/b/libyae2f0aa15c9e92/p <span class="nt">--with-readline-dir</span><span class="o">=</span>/Users/julien/.conan2/p/b/readl0d0041a63fa03/p <span class="nt">--with-gmp-dir</span><span class="o">=</span>/Users/julien/.conan2/p/b/gmp676fa41eaa3d6/p <span class="nt">--with-opt-dir</span><span class="o">=</span>/Users/julien/.conan2/p/b/opense854e464e8ff6/p:/Users/julien/.conan2/p/b/libff05fe9d5b96f79/p:/Users/julien/.conan2/p/b/libyae2f0aa15c9e92/p:/Users/julien/.conan2/p/b/readl0d0041a63fa03/p:/Users/julien/.conan2/p/b/gmp676fa41eaa3d6/p <span class="nt">--disable-jit-support</span>
</code></pre>
<p>I have tried to backport <a href="https://github.com/ruby/ruby/pull/6296/files" class="external">https://github.com/ruby/ruby/pull/6296/files</a> and <a href="https://github.com/ruby/ruby/commit/48644e71096c70132be9dfdcbfb414ec2e68d18b" class="external">https://github.com/ruby/ruby/commit/48644e71096c70132be9dfdcbfb414ec2e68d18b</a> and <a href="https://github.com/ruby/ruby/pull/8730" class="external">https://github.com/ruby/ruby/pull/8730</a> amongst other things but I can't make it work. (I even tried a more brute force approach patching a lot of files by diffing 3.3.0 with 3.1.0, but please note I don't know what I'm doing... and I can get to the install step but then I get some errors about Psych / libymal and undefined Gem::Install:Zlib).</p>
<p>I would <strong>greatly</strong> appreciate if someone can spare some time to help me wrap this up (I've been trying to make the recipe work for so long that I'm about to give up...)</p> Ruby master - Misc #20238 (Open): Use prism for mk_builtin_loader.rbhttps://bugs.ruby-lang.org/issues/202382024-02-05T20:52:02Zkddnewton (Kevin Newton)kddnewton@gmail.com
<p>I would like to propose that we use prism for mk_builtin_loader.rb.</p>
<p>Right now the Ruby syntax that you can use in builtin classes is restricted to the base Ruby version (2.7). This means you can't use a lot of the nicer syntax that Ruby has shipped in the last couple of years.</p>
<p>If we switch to using prism to parse the builtin files instead of using ripper, then we can always use the latest version of Ruby syntax. A pull request for this is here: <a href="https://github.com/kddnewton/ruby/pull/65" class="external">https://github.com/kddnewton/ruby/pull/65</a>. The approach for the PR is taken from how RJIT bindgen works.</p> Ruby master - Misc #20232 (Open): Document Kernel#require and Module#autoload concurrency guaranteeshttps://bugs.ruby-lang.org/issues/202322024-02-01T05:20:04Zfxn (Xavier Noria)fxn@hashref.com
<p>I'd like to document <code>Kernel#require</code> and <code>Module#autoload</code> concurrency guarantees.</p>
<p>In the case of multiple threads loading the same file concurrently, <code>Kernel#require</code> will succeed in just one of them and the rest will wait and return false. If a constant that has an autoload is concurrently referenced, the same can be said. Assuming no errors, only one thread will succeed, and the rest wait. There will be no context switching in the middle of an autoload that will result in a <code>NameError</code> in other threads waiting for that constant.</p>
<p>Now, I'd like to have a discussion about those guarantees with fibers.</p>
<p>In the case of manually managed fibers, users can enter a deadlock by hand:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># This produces a deadlock.</span>
<span class="no">File</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="s1">'/tmp/bar.rb'</span><span class="p">,</span> <span class="o"><<~</span><span class="no">RUBY</span><span class="p">)</span><span class="sh">
Fiber.yield
</span><span class="no">RUBY</span>
<span class="no">Fiber</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="nb">require</span> <span class="s1">'/tmp/bar.rb'</span> <span class="p">}.</span><span class="nf">resume</span>
<span class="no">Fiber</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="nb">require</span> <span class="s1">'/tmp/bar.rb'</span> <span class="p">}.</span><span class="nf">resume</span>
</code></pre>
<p>If this is expected, I guess users should be told this is a possibility in the API dosc? Because from a user perspective, you don't really have elements to anticipate a deadlock there if the docs don't warn you.</p>
<p>A similar deadlock can be triggered with an <code>autoload</code> instead of a <code>require</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># This produces a deadlock.</span>
<span class="no">File</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="s1">'/tmp/bar.rb'</span><span class="p">,</span> <span class="o"><<~</span><span class="no">RUBY</span><span class="p">)</span><span class="sh">
Fiber.yield
Bar = 1
</span><span class="no">RUBY</span>
<span class="nb">autoload</span> <span class="ss">:Bar</span><span class="p">,</span> <span class="s1">'/tmp/bar.rb'</span>
<span class="no">Fiber</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="no">Bar</span> <span class="p">}.</span><span class="nf">resume</span>
<span class="no">Fiber</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="no">Bar</span> <span class="p">}.</span><span class="nf">resume</span>
</code></pre>
<p>A different matter is fibers managed by fiber schedulers. I have not been able to enter a deadlock with the fiber schedulers I have tried, but from the point of view of the user, doing something like I/O or sleeping at the top-level is not unlike that manual <code>Fiber.yield</code> above. The contract for fiber schedulers is mostly an interface, but it does not address this, at least in an explicit way. Do fiber schedulers guarantee anything about this with the current contract?</p>
<p>I'd be glad to volunteer docs with the conclusions of this thread.</p> Ruby master - Misc #20170 (Open): Drop support for GCC < 11https://bugs.ruby-lang.org/issues/201702024-01-09T13:40:59Zkddnewton (Kevin Newton)kddnewton@gmail.com
<p>Right now, CI compiles everything from GCC 7+. However, GCC 7-10 are all end-of-life and no longer supported. We should drop support for the end-of-life compilers.</p> Ruby master - Misc #20156 (Open): C99 updateshttps://bugs.ruby-lang.org/issues/201562024-01-05T23:11:12Zkddnewton (Kevin Newton)kddnewton@gmail.com
<p>Now that we require Visual Studio 2015 and Oracle Developer Studio 12.5, we can do a couple of things to clean up:</p>
<ul>
<li>We should be able to remove our custom <code>stdbool.h</code> (added in VS2015 and Oracle SS 12.3)</li>
<li>Remove our usage of <code>__restrict</code> for Windows (added in VS2015)</li>
<li>Remove our custom <code>va_copy</code> (added in VS2015)</li>
</ul>
<p>Just notating, a couple of things that we <em>can</em> use now:</p>
<ul>
<li>snprintf</li>
<li>size_t printf format specifier (%z)</li>
</ul>
<p>I'm happy to do this work, but I wanted to open this ticket in case there is something besides Visual Studio or Oracle Solaris Studio that I would have missed for one of our compilation targets. Are there any other targets that do not fully implement C99?</p> Ruby master - Misc #20013 (Open): Travis CI statushttps://bugs.ruby-lang.org/issues/200132023-11-21T14:10:56Zjaruga (Jun Aruga)
<p>I would like to use this ticket to manage our activities to report Travis CI status.</p>
<p>Because there is Travis CI status page provided by Travis CI. However, even when the page shows ok, I actually see infra issues.<br>
<a href="https://www.traviscistatus.com/" class="external">https://www.traviscistatus.com/</a></p>
<p>I would share my activities and report the Travis CI status on the ticket.<br>
The ticket's status is not closed until we stop using Travis CI.</p>
<p>The easiest option to fix the Travis infra issue is to email Travis CI support <code>support _AT_ travis-ci.com</code>.</p>
<p>You can check <a href="https://github.com/ruby/ruby/wiki/CI-Servers#travis-ci" class="external">this ruby/ruby Travis CI wiki page</a> for details.</p> Ruby master - Misc #19971 (Open): Confusing arity of a Proc with implicit rest parameterhttps://bugs.ruby-lang.org/issues/199712023-10-24T13:07:51Zandrykonchin (Andrew Konchin)
<p>I've noticed that such proc <code>proc { |a,| }</code> has arity <code>1</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">proc</span> <span class="p">{</span> <span class="o">|</span><span class="n">a</span><span class="p">,</span><span class="o">|</span> <span class="p">}.</span><span class="nf">arity</span> <span class="c1"># => 1</span>
</code></pre>
<p>that means only one required parameter, but the proc behaves similar to a proc with explicit rest parameter (<code>proc { |a, *| }</code>) that has arity <code>-2</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">proc</span> <span class="p">{</span> <span class="o">|</span><span class="n">a</span><span class="p">,</span> <span class="o">*|</span> <span class="p">}.</span><span class="nf">arity</span> <span class="c1"># => -2</span>
</code></pre>
<p>that means one required parameter and rest parameter.</p>
<p>So I am wondering whether it's intentional behaviour and what the rational is behind it.</p> Ruby master - Misc #19912 (Open): [Small potential for slight improvement in regards to trailing ...https://bugs.ruby-lang.org/issues/199122023-10-06T05:57:07ZrubyFeedback (robert heiler)
<p>Not sure if I should file this under bug or not; it is probably not a bug per se<br>
and just the current behaviour. So I filed it under Misc here.</p>
<p>So let me copy/paste the code next:</p>
<pre><code>alias e puts
i = 'abc'
case i
when /help
e 'No help options are currently documented.'
when /-?-?rotate=(\d+)$/i
pp $1.to_s
exit
end
end
</code></pre>
<p>I isolated this from a larger .rb file. I was adding support for<br>
--rotate= for a class tasked with commandline stuff in regards to<br>
.pdf files, e. g. rotating wrong .pdf files.</p>
<p>When I run this .rb file, that is the one I showed above, I get<br>
the following error, as-is (the extra "end" is kind of deliberate,<br>
I had a much larger case/when structure before).</p>
<pre><code>foo.rb: --> foo.rb
Unmatched `end', missing keyword (`do', `def`, `if`, etc.) ?
> 4 i = 'abc'
> 6 case i
> 7 when /help
> 8 e 'No help options are currently documented.'
> 9 when /-?-?rotate=(\d+)$/i
> 12 end
> 14 end
foo.rb:9: syntax error, unexpected backslash (SyntaxError)
when /-?-?rotate=(\d+)$/i
^
</code></pre>
<p>Because there are at the least two problems in this .rb file,<br>
it appears to be that the ruby parser focuses on the last<br>
error found. To those who can not instantly find the error,<br>
I simply forgot a trailing / in the case/when menu, at<br>
"when /help". That actually was the real bug too. But I first<br>
looked down, where ruby alerted me that there is an issue<br>
with "when /-?-?rotate=(\d+)$/i". The real problem was the<br>
missing "/".</p>
<p>Is there potential to improve handling of such small mistakes,<br>
specifically someone forgetting a trailing / in a case/when<br>
menu? I assume ruby has to decide what is going on, but usually<br>
when I use a case/when menu, I have multiple such entries, so<br>
perhaps this gives the ruby parser additional information it<br>
could use, such as: "look at the immediate surrounding and<br>
then determine whether this may be a missing /".</p>
<p>I don't know how difficult it is to add that, and if it is too<br>
much work then I think the time may be spent elsewhere. But on<br>
the other hand, if the ruby parser could detect such small<br>
mistakes more easily (a forgotten /), this would be rather nice<br>
to have.</p>
<p>This may also have to do with how ruby reports errors; I guess<br>
the part "Unmatched <code>end', missing keyword (</code>do', <code>def</code>, <code>if</code>,<br>
etc.) ?" is ruby's attempt to give useful information to the<br>
user, and in many cases this should work. But in case of simple<br>
errors such as the above it may not work, and secondary errors<br>
may disguise or confuse the user momentarily. I usually look at<br>
the last part of any long trace shown by the ruby parser to me,<br>
so that is why I sometimes miss prior errors.</p> Ruby master - Misc #19767 (Open): [Not really a bug, but more a not ideal notification] "historic...https://bugs.ruby-lang.org/issues/197672023-07-14T08:10:20ZrubyFeedback (robert heiler)
<p>To get my knowledge about ruby regexes up-to-date I have been<br>
going through this tutorial/book here at:</p>
<p><a href="https://learnbyexample.github.io/Ruby_Regexp/unicode.html" class="external">https://learnbyexample.github.io/Ruby_Regexp/unicode.html</a></p>
<p>One example they provide is this, with some odd characters:</p>
<pre><code>'fox:αλεπού'.scan(/\w+/n)
</code></pre>
<p>This will match the found word ("fox"), but it also reports<br>
the following warning:</p>
<pre><code>warning: historical binary regexp match /.../n against UTF-8 string
</code></pre>
<p>Now: this may be obvious to others, but to me personally I am not<br>
sure what a "historical" binary regexp match actually is. I assume<br>
it may have meant that this was more used in the past, and may be<br>
discouraged now? Or is something else meant? What does "historical"<br>
mean in this context?</p>
<p>I may not be the only one who does not fully understand the term<br>
historical. Most of ruby's warnings are fairly easy to understand,<br>
but this one seems odd. Right now I do not know whether we can use<br>
the "n" modifier in a regex - not that I really have a good use<br>
case for it (I am using UTF-8 these days, so I don't seem to need<br>
ASCII-8BIT anyway), but perhaps the warning could be changed a little.</p>
<p>I have no good alternative suggestion how it can be changed, largely<br>
because I do not know what it actually means, e. g. what is "historical"<br>
about it (but, even then, I'd actually recommend against using the<br>
word "historical" because I don't understand what it means; deprecated<br>
is easy to understand, historical does not tell me anything).</p>
<p>Perhaps it could be expressed somewhat differently and we could get<br>
rid of the word "historical" there? Either way, it's a tiny issue so<br>
I was not even sure whether to report it. But, from the point of view<br>
of other warnings, I believe the term "historical" does not tell the<br>
user enough about what the issue is here.</p>
<p>(irb):1: warning: historical binary regexp match /.../n against UTF-8 string<br>
=> ["fox"]</p> Ruby master - Misc #19692 (Open): Net::HTTP Performance Workstreamhttps://bugs.ruby-lang.org/issues/196922023-05-24T20:21:17Zbaweaver (Brandon Weaver)keystonelemur@gmail.com
<p>While working on identifying causes behind Capybara test slowness I had noticed some memory profiles pointed at a few slow code paths in <code>Net::HTTP</code>, one of which I've already opened a PR for here:</p>
<p><a href="https://github.com/ruby/net-http/pull/140" class="external">https://github.com/ruby/net-http/pull/140</a></p>
<p>The reason I'm opening this ticket is that I had found some additional areas which warrant investigation for some decent performance gains in frequently run sections of code in <code>Net::HTTP</code> and to ask if someone would be willing to work with me on opening likely several PRs against the code base in the near future.</p>
<p>I will hold myself to the standard of qualifying these changes with performance data on which parts are frequently run and are slow, but would appreciate working with someone from core through this.</p> Ruby master - Misc #19691 (Open): File.realpath on Windows does not return actual case of the filehttps://bugs.ruby-lang.org/issues/196912023-05-24T15:22:53ZMSP-Greg (Greg L)
<p>I don't know what I think of this (expected or bug), but recently in a forum I saw an issue that I don't recall accidentally doing myself. An equivalent example:</p>
<pre><code>ruby -rsingleton -rSingleton -e "puts 'case issue'"
</code></pre>
<p>Note the change of casing with <code>Singleton</code>.</p>
<p>On case insensitive file systems, the above will double load the file, which errors.</p>
<p>Obviously, on case sensitive file systems, it errors with <code>cannot load such file -- Singleton</code></p>
<p>So, options are:</p>
<p>A. No change to current behavior, which I'm fine with.</p>
<p>B. If the OS is case insensitive, don't reload the file, and maybe a warning that <code>Singleton</code> and <code>singleton</code> are equivalent.</p> Ruby master - Misc #19421 (Open): Distribution documentationhttps://bugs.ruby-lang.org/issues/194212023-02-07T05:03:49Zioquatix (Samuel Williams)samuel@oriontransfer.net
<p>I use Ruby a lot, on a lot of different systems, and help people and companies use it, including developers who install it on their systems.</p>
<p>Over time, I found that installing Ruby isn't always easy. Part of this is due to package management. There are many systems, and Ruby has had some tricky migrations (e.g. OpenSSL is probably one of the most painful ones that lots of developers have trouble with).</p>
<p>Arch Linux has been stuck on Ruby 3.0 for a long time, which could be considered surprising given that Arch Linux is often on the bleeding edge of releases. I personally use Arch too. So I decided to ask, what is holding them up from making a release?</p>
<p>I found out they had many questions about how to distribute Ruby correctly. When I listened to those questions I felt that there are many ambiguities in how we build and package Ruby for operating system packages. This isn't to say that there isn't a good way to do it, just that we as a core team might be able to improve our communication about how Ruby is evolving and the implications for package managers (if any).</p>
<p>I've introduced <code>doc/distribution.md</code> as an effort to start having better documentation for people distributing Ruby. There are many ways which people distribute Ruby, and many "partial" documentation or assumptions being made about how to distribute Ruby and I'd like to provide a convenient standard location that can help people build package for Ruby distribution. Ultimately this makes my job easier because the latest versions of Ruby will be easier to install, so that's what I care about, but I don't care about what specifically is in the document, except that I think we should listen to the kinds of questions being asked and, in the best interest of Ruby, provide guidance.</p>
<p>There was a lot of good discussion on the PR, but my goal is not to make a finished document, but instead plant the seed so it can grow.</p>
<p><a href="https://github.com/ruby/ruby/pull/6856" class="external">https://github.com/ruby/ruby/pull/6856</a></p>
<p>Some follow up discussion is required:</p>
<ul>
<li>
<p>What is the best practice for building source packages. The documentation I wrote from this was removed as "out of scope" but I disagree with that (<a href="https://github.com/ruby/ruby/commit/c35ebed895e1a3f7bced3db50ea0db8f284744e8" class="external">https://github.com/ruby/ruby/commit/c35ebed895e1a3f7bced3db50ea0db8f284744e8</a>). I don't have a strong opinion about what it should look like, but I think we should give a clear example of how to build source packages like what I wrote.</p>
</li>
<li>
<p>Related to the above, what is the official location for source tarballs?</p>
</li>
<li>
<p>What optional dependencies are required for building vs distributing Ruby. Arch Linux currently lists: <code>doxygen gdbm graphviz libffi libyaml openssl ttf-dejavu tk</code> as dependencies but it's not clear if this list is up to date, or what the expectations are. When someone installs Ruby (e.g. <code>apt-get install ruby</code>) what dependencies should be installed? I think it would be helpful to list expected dependencies (from a system package POV), etc.</p>
</li>
<li>
<p>Is Ruby needed for building Ruby? Should source packages install Ruby before building from source? If so, what versions are supported?</p>
</li>
<li>
<p>Clear guidance on gems that are distributed an alongside Ruby, and how security changes to gems are managed.</p>
</li>
</ul>
<p>Even if we have more detailed documentation elsewhere, let's summarise it and then cross-reference it. People who build packages to distribute and install Ruby should feel supported, they are very important to our community. To this end, I established <code>#distribution</code> channel on Slack for discussion. We should listen to the questions being asked and use those questions to drive improvements to documentation.</p> Ruby master - Misc #19391 (Open): IO #write/#read behaviour when binmode and encoding are explici...https://bugs.ruby-lang.org/issues/193912023-01-30T10:19:05Zandrykonchin (Andrew Konchin)
<p>I have a question about how <code>IO</code> operations are supposed to behave when file is opened in binary mode but encoding is specified too.</p>
<p>Documentation of <code>b</code> option of <code>IO.new</code> method and of <code>IO#binmode</code> method is a bit not synchronised and confusing:</p>
<p><code>IO.open</code>:</p>
<pre><code>"b" Binary file mode
Suppresses EOL <-> CRLF conversion on Windows. And
sets external encoding to ASCII-8BIT unless explicitly
specified.
</code></pre>
<p><code>IO#binmode</code>:</p>
<pre><code>Puts ios into binary mode. Once a stream is in binary mode, it cannot be reset to nonbinary mode.
newline conversion disabled
encoding conversion disabled
content is treated as ASCII-8BIT
</code></pre>
<p>So <code>unless explicitly specified</code> and <code>encoding conversion disabled</code> are a bit contradictory.</p>
<p>Right now I observe that <code>IO.write</code> still encodes an input string in explicitly specified encoding (with <code>encoding</code> option) even if binary mode is set (with <code>binmode</code> option)</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="vi">@filename</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">,</span> <span class="ss">encoding: </span><span class="no">Encoding</span><span class="o">::</span><span class="no">UTF_32LE</span><span class="p">,</span> <span class="ss">binmode: </span><span class="kp">true</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">file</span><span class="o">|</span>
<span class="n">file</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="s2">"hi"</span><span class="p">)</span>
<span class="k">end</span>
<span class="no">File</span><span class="p">.</span><span class="nf">binread</span><span class="p">(</span><span class="vi">@filename</span><span class="p">)</span> <span class="c1"># => "h\u0000\u0000\u0000i\u0000\u0000\u0000"</span>
</code></pre> Ruby master - Misc #19176 (Open): Missing insns_info for iseqs in ruby 3.2 built with debug optionshttps://bugs.ruby-lang.org/issues/191762022-12-03T13:25:59Zhurricup (Alexandr Evstigneev)hurricup@gmail.com
<p>I'm not quite sure it is a proper place to ask questions, correct me if I'm wrong.<br>
But I have a problem with ruby-3.2.0 previews. Looks like iseq is missing <code>insns_info</code>s.</p>
<p>It works fine in with pre-3.2 rubies but seems something has changed and I can't figure out - what exactly.</p>
<p>It looks like this:<br>
<img src="https://bugs.ruby-lang.org/attachments/download/9375/clipboard-202212031723-don1h.png" alt="" loading="lazy"></p>
<p>You may see that body, supposed to be a pointer to <code>iseq_insn_info_entry</code> contains some 0x7 pointing nowhere. And <code>size</code> for <code>insns_info</code> in all <code>iseq</code> I can find with iterating objspace is zero.</p> Ruby master - Misc #19142 (Open): Run test suites against 'install', based on ENV variable?https://bugs.ruby-lang.org/issues/191422022-11-22T22:39:07ZMSP-Greg (Greg L)
<p>Some time ago I believe there was discussion about:</p>
<pre><code>make
make test
make install
</code></pre>
<p>vs</p>
<pre><code>make
make install
make test
</code></pre>
<p>Some people preferred to not have to run install before test (disk space, time, etc).</p>
<p>Might an environment variable like <code>RUBY_TEST_FROM_INSTALL</code> or <code>RUBY_TEST_FROM_PATH</code> be<br>
added that would trigger the test suite to test against the Ruby install folder or the<br>
Ruby in PATH?</p>
<p>I believe a handful of files in the test system would need changes, as they load files<br>
using <code>require_relative</code>...</p>
<p>I think spec/mspec is already setup to do so.</p> Ruby master - Misc #19131 (Open): MatchData#values_at(): addressing with Range and Integer index ...https://bugs.ruby-lang.org/issues/191312022-11-15T15:33:18Zandrykonchin (Andrew Konchin)
<p>I've noticed a strange nuance and not sure whether it's intentional or not. In case it's intentional - it seems to me inconsistent.</p>
<p>I will illustrate it with the following example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="sr">/(.)(.)(.)(.)/</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="s2">"abcde"</span><span class="p">).</span><span class="nf">values_at</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="o">..-</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># => ["abcd", "a", "b", "c", "d"]</span>
<span class="sr">/(.)(.)(.)(.)/</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="s2">"abcde"</span><span class="p">).</span><span class="nf">values_at</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">)</span> <span class="c1"># => [nil]</span>
</code></pre>
<p>So with a negative index we can address the whole matched string (<code>0</code> element) with a Range argument but cannot with an Integer index.</p>
<p>We can index with negative values only captured values:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="sr">/(.)(.)(.)(.)/</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="s2">"abcde"</span><span class="p">).</span><span class="nf">values_at</span><span class="p">(</span><span class="o">-</span><span class="mi">4</span><span class="p">)</span> <span class="c1"># => ["a"]</span>
<span class="sr">/(.)(.)(.)(.)/</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="s2">"abcde"</span><span class="p">).</span><span class="nf">values_at</span><span class="p">(</span><span class="o">-</span><span class="mi">3</span><span class="p">)</span> <span class="c1"># => ["b"]</span>
<span class="sr">/(.)(.)(.)(.)/</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="s2">"abcde"</span><span class="p">).</span><span class="nf">values_at</span><span class="p">(</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span> <span class="c1"># => ["c"]</span>
<span class="c1"># ...</span>
</code></pre>
<p>I would expect <code>Range</code> and <code>Integer</code> arguments are handled consistently and either both allow to address the first element with negative index or both disallow it.</p>
<hr>
<pre><code>ruby -v
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-darwin21]
</code></pre> Ruby master - Misc #19123 (Open): Error handling of Struct#values_at and Array#values_at is sligh...https://bugs.ruby-lang.org/issues/191232022-11-11T17:29:41Zandrykonchin (Andrew Konchin)
<p><code>Struct#values_at</code> and `Array#values_at look pretty similar and handle all the complex cases of arguments (integer Ranges, list of Integers and mixing Ranges and Integers) in the same way.</p>
<p>Error handling is similar as well. In case of invalid Range argument they behave identically:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">clazz</span> <span class="o">=</span> <span class="no">Struct</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">:name</span><span class="p">,</span> <span class="ss">:director</span><span class="p">,</span> <span class="ss">:year</span><span class="p">)</span>
<span class="n">movie</span> <span class="o">=</span> <span class="n">clazz</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s1">'Sympathy for Mr. Vengeance'</span><span class="p">,</span> <span class="s1">'Chan-wook Park'</span><span class="p">,</span> <span class="mi">2002</span><span class="p">)</span>
<span class="n">array</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span>
<span class="c1"># end is out of range </span>
<span class="n">movie</span><span class="p">.</span><span class="nf">values_at</span><span class="p">(</span><span class="mi">0</span><span class="o">..</span><span class="mi">4</span><span class="p">)</span> <span class="c1"># => ["Sympathy for Mr. Vengeance", "Chan-wook Park", 2002, nil, nil]</span>
<span class="n">array</span><span class="p">.</span><span class="nf">values_at</span><span class="p">(</span><span class="mi">0</span><span class="o">..</span><span class="mi">4</span><span class="p">)</span> <span class="c1"># => [0, 1, 2, nil, nil]</span>
<span class="c1"># beginning is out of range</span>
<span class="n">movie</span><span class="p">.</span><span class="nf">values_at</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="o">..</span><span class="mi">4</span><span class="p">)</span> <span class="c1"># -5..4 out of range (RangeError)</span>
<span class="n">array</span><span class="p">.</span><span class="nf">values_at</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="o">..</span><span class="mi">4</span><span class="p">)</span> <span class="c1"># -5..4 out of range (RangeError)</span>
</code></pre>
<p>But when Integer argument is passed - they handle out of range cases differently:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># end is out of range </span>
<span class="n">movie</span><span class="p">.</span><span class="nf">values_at</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span> <span class="c1"># => offset 4 too large for struct(size:3) (IndexError)</span>
<span class="n">array</span><span class="p">.</span><span class="nf">values_at</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span> <span class="c1"># => [nil]</span>
<span class="c1"># beginning is out of range</span>
<span class="n">movie</span><span class="p">.</span><span class="nf">values_at</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">)</span> <span class="c1"># => offset -5 too small for struct(size:3) (IndexError)</span>
<span class="n">array</span><span class="p">.</span><span class="nf">values_at</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">)</span> <span class="c1"># => [nil]</span>
</code></pre>
<p>So I am wondering what is the reason of such inconvenience. I suppose there may be a reason of this difference. But I see some benefits in consistent error handling.</p> Ruby master - Misc #19121 (Open): Time: utc offset argument's formats "+/-HH", "+/-HHMM", "+/-HHM...https://bugs.ruby-lang.org/issues/191212022-11-11T14:50:11Zandrykonchin (Andrew Konchin)
<p>I've noticed a strange difference between Ruby versions 2.7, 3.0 and 3.1.</p>
<p>The mentioned above formats are supported in Ruby 2.7 and Ruby 3.1 but aren't supported in Ruby 3.0.</p>
<p>So I am wondering whether supporting these formats is expected behaviour or a bug. In any case I would expect consistent behaviour in all the supported Ruby versions.</p>
<p>Ruby 2.7.4</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Time</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">2000</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"+05"</span><span class="p">)</span> <span class="c1"># => 2000-01-01 00:00:00 +0500</span>
<span class="no">Time</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">2000</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"+0530"</span><span class="p">)</span> <span class="c1"># => 2000-01-01 00:00:00 +0530</span>
<span class="no">Time</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">2000</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"+053037"</span><span class="p">)</span> <span class="c1"># => 2000-01-01 00:00:00 +0530</span>
</code></pre>
<p>Ruby 3.0.4</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Time</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">2000</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"+05"</span><span class="p">)</span>
<span class="c1">#(irb):1:in `initialize': "+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset (ArgumentError)</span>
<span class="no">Time</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">2000</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"+0530"</span><span class="p">)</span>
<span class="c1">#(irb):2:in `initialize': "+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset (ArgumentError)</span>
<span class="no">Time</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">2000</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"+053037"</span><span class="p">)</span>
<span class="c1">#(irb):3:in `initialize': "+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset (ArgumentError)</span>
</code></pre>
<p>Ruby 3.1.2</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Time</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">2000</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"+05"</span><span class="p">)</span> <span class="c1"># => 2000-01-01 00:00:00 +0500</span>
<span class="no">Time</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">2000</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"+0530"</span><span class="p">)</span> <span class="c1"># => 2000-01-01 00:00:00 +0530</span>
<span class="no">Time</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">2000</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"+053037"</span><span class="p">)</span> <span class="c1"># => 2000-01-01 00:00:00 +053037</span>
</code></pre> Ruby master - Misc #19098 (Open): Time#strftime: %z and widthhttps://bugs.ruby-lang.org/issues/190982022-11-01T17:49:20Zandrykonchin (Andrew Konchin)
<p>It seems <code>%z</code> behaves in some surprising way when it is combined with a width - sign <code>+</code> is placed at the beginning of the result string:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Time</span><span class="p">.</span><span class="nf">now</span><span class="p">.</span><span class="nf">strftime</span><span class="p">(</span><span class="s2">"%10z"</span><span class="p">)</span>
<span class="o">=></span> <span class="s2">"+000000200"</span>
<span class="no">Time</span><span class="p">.</span><span class="nf">now</span><span class="p">.</span><span class="nf">strftime</span><span class="p">(</span><span class="s2">"%_10z"</span><span class="p">)</span>
<span class="o">=></span> <span class="s2">" +200"</span>
</code></pre>
<p>It seems a time zone offset is treated as a number. It probably makes sense with default format but it looks strange with <code>:</code> separators:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Time</span><span class="p">.</span><span class="nf">now</span><span class="p">.</span><span class="nf">strftime</span><span class="p">(</span><span class="s2">"%10::z"</span><span class="p">)</span>
<span class="c1"># => "+002:00:00"</span>
</code></pre>
<p>So I would expect that <code>%z</code> directive output to be treated as a non-numerical and padded by default with spaces.</p> Ruby master - Misc #19052 (Open): Increased memory usage (RSS) for Ruby when compiled by gcchttps://bugs.ruby-lang.org/issues/190522022-10-14T00:16:31Zbosh-ecosystem-vmware (BOSH Ecosystem Team @ VMware)
<p>Hello! We have seen a large increase in memory usage as measured by resident set size (RSS) in our Ruby 3.1.2 programs when testing on Ubuntu Jammy (22.04). After further testing, we have narrowed down the problem as starting with Ubuntu Eoan (19.10). We first noticed this increase coming from a gem called <code>eventmachine v1.2.7</code>, which is a concurrency library that uses threads internally. That led us to try threads directly, and we came up with a simple Ruby program that reproduces the memory usage issue by spawning multiple threads through <code>Thread.new</code>.</p>
<p>We are unsure whether the problem extends beyond just <code>Thread.new</code>; it was the easiest problem to spot within our applications.</p>
<p>We are building Ruby from source using <code>ruby-install</code>, though have seen the problem in versions installed via <code>apt</code>.</p>
<p>We are seeking to understand the underlying cause of this memory bloat, and what we can do to prevent it.</p>
<p>Generally, we've been seeing similar total virtual memory allocated, only a difference in RSS usage.</p>
<p>On Ubuntu Disco (19.04) and prior, we see a relatively small increase in RSS upon spawning the threads, on the order of 20 kilobytes per thread. On Ubuntu Eoan and later, we see that RSS increases by 1 megabyte per thread.</p>
<p>When Ruby is compiled using <code>clang</code> instead of <code>gcc</code> on Ubuntu Eoan and later, the memory usage is comparable to older versions of Ubuntu.</p>
<p>We do not believe it is related to gcc version <em>by itself</em>, as we tried compiling Ruby using gcc 9 on Ubuntu Disco, and did not encounter the memory problem. On the theory that it may be a memory fragmentation issue, we tried both using the <code>MALLOC_ARENA_MAX</code> runtime environment variable, and compiling Ruby against <code>jemalloc</code>. Neither of these reduced RSS usage.</p>
<p>Here are the memory differences when simply calling <code>Thread.new</code> 10 times:</p>
<table>
<thead>
<tr>
<th>Configuration</th>
<th>RSS before spawning threads</th>
<th>RSS after spawning threads</th>
<th>Diff</th>
</tr>
</thead>
<tbody>
<tr>
<td>Disco + gcc 8</td>
<td>13596 kB</td>
<td>13800 kB</td>
<td>204 kB</td>
</tr>
<tr>
<td>Disco + gcc 9</td>
<td>13880 kB</td>
<td>14088 kB</td>
<td>208 kB</td>
</tr>
<tr>
<td>Eoan + gcc 9</td>
<td>22268 kB</td>
<td>32672 kB</td>
<td>10404 kB</td>
</tr>
<tr>
<td>Eoan + clang</td>
<td>13976 kB</td>
<td>14180 kB</td>
<td>204 kB</td>
</tr>
<tr>
<td>Jammy + gcc 11</td>
<td>22208 kB</td>
<td>32608 kB</td>
<td>10400 kB</td>
</tr>
<tr>
<td>Jammy + clang</td>
<td>13668 kB</td>
<td>13872 kB</td>
<td>204 kB</td>
</tr>
<tr>
<td>Jammy + jemalloc</td>
<td>24212 kB</td>
<td>35216 kB</td>
<td>11004 kB</td>
</tr>
<tr>
<td>Jammy + apt</td>
<td>21308 kB</td>
<td>31712 kB</td>
<td>10404 kB</td>
</tr>
</tbody>
</table>
<p>We have attached the program and a series of Dockerfiles that replicate the test environments. While the reproduction is using Docker files, we have seen this same behavior on actual VMs. To run a particular Docker config, use <code>./run.sh <DIRECTORY></code>, e.g. <code>./run.sh jammy-clang</code>.</p>
<p>Does anyone understand why there is an increase in resident set size (RSS) when Ruby is compiled with gcc vs clang?<br>
Is there additional configuration (flags, etc) that could be sent to gcc to get equivalent memory usage on Jammy that is seen when using Disco or clang?</p> Ruby master - Misc #18984 (Open): Doc for Range#size for Float/Rational does not make sensehttps://bugs.ruby-lang.org/issues/189842022-08-29T14:39:13Zmasasakano (Masa Sakano)
<p>When <code>Range</code> consists of any Numeric, according to <a href="https://ruby-doc.org/core-3.1.2/Range.html#method-i-size" class="external">Official docs for Ruby-3.1.2</a>, <code>Range#size</code> should,</p>
<blockquote>
<p>Returns the count of elements in self if both begin and end values are numeric;</p>
</blockquote>
<p>Indeed, when <code>Range</code> consists of only <code>Integer</code>, this makes sense.<br>
However, when the begin value of <code>Range</code> is a <code>Float</code> or <code>Rational</code>, "<em>the count of elements</em>" does not make sense. Such Ranges are not iteratable, suggesting there are no such things as "elements":</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">(</span><span class="mf">0.51</span><span class="o">..</span><span class="mi">5</span><span class="p">.</span><span class="nf">quo</span><span class="p">(</span><span class="mi">2</span><span class="p">)).</span><span class="nf">each</span><span class="p">{}</span> <span class="c1"># => TypeError</span>
</code></pre>
<p>Yet, <code>Range#size</code> of such Ranges returns an Integer</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">(</span><span class="mf">0.51</span><span class="o">..</span><span class="mi">5</span><span class="p">.</span><span class="nf">quo</span><span class="p">(</span><span class="mi">2</span><span class="p">)).</span><span class="nf">size</span> <span class="c1"># => 2</span>
</code></pre>
<p>It seems both begin and end values of a Range are rounded (<code>Numeric#round</code>) to the nearest Integer before <code>Range#size</code> is calculated.</p>
<p>If this is the specification, I suggest it should be clearly stated in the <a href="https://ruby-doc.org/core-3.1.2/Range.html#method-i-size" class="external">Official docs</a>, avoiding the confusing expression "the count of elements", because "elements" are not unambiguously defined for Range of Float/Rational.</p> Ruby master - Misc #18924 (Open): lstrlen and lstrcat still in usehttps://bugs.ruby-lang.org/issues/189242022-07-17T20:42:52Ztest35965@gmail.com (Alexander Riccio)
<p>In practice, as-used, this is probably benign, but is a Terrible Idea.</p>
<p>There are several places where someone's still using lstrcat and lstrlen in ruby.</p>
<p>lstrcat catches and <em><strong>suppresses</strong></em> access violations. I have been burned by this in the wild as a user of other software, corrupting data and causing mysterious crashes. There's no good reason to use these functions. IIRC, they may even date back to before the standard library was standard (on windows?)?</p>
<p>Swapping them for standard functions like strcpy is not great, but can only break code that was incorrect and memory-corrupting already.</p> Ruby master - Misc #18921 (Open): Remove workaround for some fixed bug (llvm.4898 & 38095)?https://bugs.ruby-lang.org/issues/189212022-07-16T15:52:40ZChandler (Chandler Hen)
<p>I notice a workaround for llvm.4898 in constant_p.h:<br>
<a href="https://github.com/ruby/ruby/blob/master/include/ruby/internal/constant_p.h" class="external">https://github.com/ruby/ruby/blob/master/include/ruby/internal/constant_p.h</a></p>
<pre><code class="c syntaxhl" data-language="c"><span class="o">*</span> <span class="n">Note</span> <span class="n">that</span> <span class="n">__builtin_constant_p</span> <span class="n">can</span> <span class="n">be</span> <span class="n">applicable</span> <span class="n">inside</span> <span class="n">of</span> <span class="kr">inline</span> <span class="n">functions</span><span class="p">,</span>
<span class="o">*</span> <span class="n">according</span> <span class="n">to</span> <span class="n">GCC</span> <span class="n">manual</span><span class="p">.</span> <span class="n">Clang</span> <span class="n">lacks</span> <span class="n">that</span> <span class="n">feature</span><span class="p">,</span> <span class="n">though</span><span class="p">.</span>
<span class="o">*</span>
<span class="o">*</span> <span class="err">@</span><span class="n">see</span> <span class="n">https</span><span class="o">:</span><span class="c1">//bugs.llvm.org/show_bug.cgi?id=4898</span>
<span class="o">*</span> <span class="err">@</span><span class="n">see</span> <span class="n">https</span><span class="o">:</span><span class="c1">//gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html</span>
<span class="err">*/</span>
<span class="cp">#include</span> <span class="cpf">"ruby/internal/has/builtin.h"</span><span class="cp">
</span>
<span class="cm">/** Wraps (or simulates) `__builtin_constant_p` */</span>
<span class="cp">#if RBIMPL_HAS_BUILTIN(__builtin_constant_p)
# define RBIMPL_CONSTANT_P(expr) __builtin_constant_p(expr)
#else
# define RBIMPL_CONSTANT_P(expr) 0
#endif
</span>
<span class="cp">#endif </span><span class="cm">/* RBIMPL_CONSTANT_P_H */</span><span class="cp">
</span></code></pre>
<p>and a workaround for llvm.38095 in scan_args.h:<br>
<a href="https://github.com/ruby/ruby/blob/master/include/ruby/internal/scan_args.h" class="external">https://github.com/ruby/ruby/blob/master/include/ruby/internal/scan_args.h</a></p>
<pre><code class="c syntaxhl" data-language="c"><span class="cm">/* NOTE: Use `char *fmt` instead of `const char *fmt` because of clang's bug*/</span>
<span class="cm">/* https://bugs.llvm.org/show_bug.cgi?id=38095 */</span>
<span class="cp"># define rb_scan_args0(argc, argv, fmt, varc, vars) \
rb_scan_args_set(RB_SCAN_ARGS_PASS_CALLED_KEYWORDS, argc, argv, \
rb_scan_args_n_lead(fmt), \
rb_scan_args_n_opt(fmt), \
rb_scan_args_n_trail(fmt), \
rb_scan_args_f_var(fmt), \
rb_scan_args_f_hash(fmt), \
rb_scan_args_f_block(fmt), \
(rb_scan_args_verify(fmt, varc), vars), (char *)fmt, varc)
</span><span class="p">...</span>
</code></pre>
<p>These bugs are already marked as fixed:<br>
bugs.llvm.org/show_bug.cgi?id=4898<br>
bugs.llvm.org/show_bug.cgi?id=38095<br>
Shall they be removed?</p> Ruby master - Misc #18840 (Open): Top-level #using and other methods docshttps://bugs.ruby-lang.org/issues/188402022-06-18T19:12:56Zzverok (Victor Shepelev)zverok.offline@gmail.com
<p>I was looking into some docs problems, and the question I have is that we don't have any place where <code>main</code>'s methods documentation is rendered?</p>
<p>The <code>#using</code>, for example, is <a href="https://github.com/ruby/ruby/blob/ruby_3_1/eval.c#L1960" class="external">defined</a> on <code>main</code>'s singleton class (if I am reading the code correctly), and it has <a href="https://github.com/ruby/ruby/blob/ruby_3_1/eval.c#L1687" class="external">RDoc defined</a> in <code>*.c</code>, but for all I can tell it is rendered nowhere.</p>
<p>Theoretically, it would've been nice to have a place where <code>main</code> object's concept would be explained and the methods available in it, listed, right?..</p>
<p>Or am I missing something obvious?</p> Ruby master - Misc #18725 (Open): IO#write and IO#wait_writable block for write pipe if read pipe...https://bugs.ruby-lang.org/issues/187252022-04-13T23:20:52Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<p>I'm not sure whether this is a Ruby issue, an OpenBSD issue, or something else, but <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/3344">@ioquatix (Samuel Williams)</a> asked me to post this here. The following program hangs on OpenBSD:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'io/wait'</span>
<span class="n">rd</span><span class="p">,</span> <span class="n">wr</span> <span class="o">=</span> <span class="no">IO</span><span class="p">.</span><span class="nf">pipe</span>
<span class="n">thread_pass</span> <span class="o">=</span> <span class="no">ARGV</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'pass'</span>
<span class="n">write</span> <span class="o">=</span> <span class="no">ARGV</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'write'</span>
<span class="n">thread</span> <span class="o">=</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">longer</span> <span class="o">=</span> <span class="s2">"0"</span> <span class="o">*</span> <span class="mi">1024</span> <span class="o">*</span> <span class="mi">1024</span>
<span class="p">(</span><span class="mi">1024</span> <span class="o">*</span> <span class="mi">4</span><span class="p">).</span><span class="nf">times</span> <span class="k">do</span>
<span class="k">if</span> <span class="n">write</span>
<span class="n">wr</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="n">longer</span><span class="p">)</span>
<span class="k">else</span>
<span class="k">while</span> <span class="n">wr</span><span class="p">.</span><span class="nf">write_nonblock</span><span class="p">(</span><span class="n">longer</span><span class="p">,</span> <span class="ss">:exception</span><span class="o">=></span><span class="kp">false</span><span class="p">)</span> <span class="o">==</span> <span class="ss">:wait_writable</span>
<span class="n">thread_pass</span> <span class="p">?</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">pass</span> <span class="p">:</span> <span class="n">wr</span><span class="p">.</span><span class="nf">wait_writable</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="ss">:finished</span>
<span class="k">rescue</span> <span class="o">=></span> <span class="n">e</span>
<span class="n">e</span>
<span class="k">end</span>
<span class="nb">sleep</span> <span class="mi">1</span>
<span class="n">rd</span><span class="p">.</span><span class="nf">close</span>
<span class="nb">puts</span> <span class="ss">:rd_close</span>
<span class="nb">puts</span> <span class="n">thread</span><span class="p">.</span><span class="nf">value</span>
</code></pre>
<p>This program will also hang if <code>write</code> is given as the argument, using <code>wr.write</code> instead of <code>wr.write_nonblock</code>/<code>wr.wait_writable</code>. However, if <code>pass</code> is given as the argument, using <code>Thread.pass</code> instead of <code>wr.wait_writable</code>, the program will not hang.</p>
<p>From testing, the hang when called without an argument is in <code>wait_writable</code>, and the hang with a <code>write</code> argument is in <code>write</code>.</p>
<p>Is Ruby supposed to guarantee that a closing the read end of a pipe in one thread causes a raise of EPIPE to the write end of the pipe in a different thread if already inside <code>IO#write</code>/<code>IO#wait_writable</code>? Or is this platform-specific behavior?</p>
<p>This example was extracted from one of Rack's tests, which was causing non-deterministic hangs on OpenBSD.</p> Ruby master - Misc #18587 (Open): What was the reason behind Ruby choosing SipHash for Hash?https://bugs.ruby-lang.org/issues/185872022-02-16T15:42:48Zmidnight (Sarun R)
<p>Hello</p>
<p>I am digging into the history behind Ruby using SipHash for its Hash.<br>
I found that in 2012 there were CVE-2012-5371 showing up;<br>
the Ruby maintainers went with the decision to switch algorithms, probably, because we wanted something quick to implement at the time.<br>
The change went live in late 2012.</p>
<p>Fast forward with the Ruby 3x3 initiative, we now seem to care about the performance again.<br>
And hash DoSing does not seem to be an urgent threat now; we have time to be deliberate about Hash again.</p>
<p>I can't find the old discussion related to Ruby's SipHash decision.<br>
I just found that SipHash is not the only solution to prevent hashtable DoSing.<br>
There is an interesting discussion on golang side in late 2015:<br>
<a href="https://github.com/golang/go/issues/9365" class="external">https://github.com/golang/go/issues/9365</a></p>
<p>Just to recap, Go's authors argue that:</p>
<ul>
<li>Cryptographic hash is not needed to construct a DoS-resistant hashtable.</li>
<li>If the random seed is per-hashtable bases, the attack vector exploitable from a remote adversary seems unlikely.</li>
<li>If we want to be extra careful about it, and since the collision is unlikely, when collision actually does occur despite the per-hashtable seed, we can handle that as a special case where we can rerandom the seed and rehash the key.</li>
<li>The way random seeds are folded into the hash does matter, for example, CityHash does f(g(msg), seed); in such case, collision in g will cause a collision in f because the output of g is independent of the seed.</li>
<li>Slowing down hashtable for everyone to prevent hard-to-exploit DoS doesn't seem to be a good trade-off.</li>
</ul>
<p>On the actual implementation, they use AES-NI to achieve good pseudo-random functions' properties. And use some fallback non-cryptographic hashing function on the platform without AES-NI.</p>
<p>Now, I read the rationale on golang side, I want to understand the rationale on the Ruby side too.<br>
I am not there 10-years-ago, and I can't find records or discussions at the time. There might be some Ruby limitations that the approach described by go's authors does not apply.</p>
<p>So, I asked in the hope of someone still remembering what was happening, the situation we are in 10 years ago, or the limitation of Ruby that prevents per-Hash seeds.</p> Ruby master - Misc #18420 (Open): Question about how to handle IO.pipe reader and writer when for...https://bugs.ruby-lang.org/issues/184202021-12-22T00:04:00Zestolfo (Emily S)
<p>I don't think this is a bug but I'm not sure. It could be just a limitation of forking with a IO.pipe reader and writer.</p>
<p>I work on the Elastic Ruby APM agent (<a href="https://github.com/elastic/apm-agent-ruby" class="external">https://github.com/elastic/apm-agent-ruby</a>). The Ruby agent is a singleton and uses a IO.pipe to send data to the APM server. The writer we wrap in a GzipWriter. When the parent process is forked, the child inherits the readers and (gzip)writers. I detect the forking by comparing PIDs when an event is created and create new readers and writers in the child process so that I don't interfere with the parent's streams.<br>
When the fork exits, I close the child's readers and writers but I see the follow error</p>
<p>zlib(finalizer): Zlib::GzipWriter object must be closed explicitly.<br>
zlib(finalizer): the stream was freed prematurely.</p>
<p>because the parent's writer is still considered living in the child process.<br>
One option to address this error is to create a finalizer on the writer that closes it. But then I get intermittent errors from the APM server saying the gzipped data's header is invalid. I'm assuming this is because the parent's writer is closed by the child before the compression is complete in the parent.</p>
<p>Is there a proper way to handle forking when the parent is using a pipe? Both options I have to handle the writer result in an error/warning: I can't close the GzipWriter in the child because of the corrupted data issue but if I don't close it, I get the "Zlib::GzipWriter object must be closed explicitly" warning.</p>
<p>If I close the reader and writer in a "before_fork" hook run in the parent, I avoid both issues. But I don't want to recreate the reader/writer objects every time the parent is forked.</p>
<p>I've been testing with ruby 2.7.0 and Resque (<a href="https://github.com/resque/resque" class="external">https://github.com/resque/resque</a>) primarily but this issue is observed with Puma and other frameworks that use forking.</p> Ruby master - Misc #18352 (Open): What is the Hash#grep expected?https://bugs.ruby-lang.org/issues/183522021-11-20T09:50:09Zzw963 (Wei Zheng)
<p>Current ruby implement, When use Array#grep, the method name means is expected.</p>
<pre><code>[19] pry(#<App>)> [:foo1, :foo2, :bar].grep /foo/
[
:foo1,
:foo2
]
</code></pre>
<p>But when use with hash, the result is really confusing ...</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="p">[</span><span class="mi">12</span><span class="p">]</span> <span class="n">pry</span><span class="p">(</span><span class="c1">#<App>)> {foo: '100', bar: '200'}.grep /foo/ </span>
<span class="p">[]</span>
</code></pre>
<p>This result almost make Include Enumerable#grep into Hash is totally meaningless, right?</p>
<p>so, i consider if we should introduce a <code>Hash#grep</code> method instead.</p>
<p>Following is what is expected. (=== is matching on hash key, as Hash#slice)</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="p">[</span><span class="mi">20</span><span class="p">]</span> <span class="n">pry</span><span class="p">(</span><span class="c1">#<App>)> {foo1: '100', foo2: '200', bar: '200'}.grep /foo/ </span>
<span class="p">{</span>
<span class="ss">:foo1</span> <span class="o">=></span> <span class="s2">"100"</span><span class="p">,</span>
<span class="ss">:foo2</span> <span class="o">=></span> <span class="s2">"200"</span>
<span class="p">}</span>
</code></pre> Ruby master - Misc #18248 (Open): Add Feature Triaging Guidehttps://bugs.ruby-lang.org/issues/182482021-10-11T16:14:14Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<p>Ruby added a bug triaging guide in June 2019, and since then I've used it to reduce the number of open bugs in the tracker from over 1400 to about 300. Ruby currently has over 1200 open feature requests on the issue tracker. From a cursory review, many of these have already been implemented, and many are unlikely to be desired. I would like to add a feature triaging guide to Ruby and start triaging feature requests, with the goal of having open feature requests be features not yet implemented that the Ruby core team would like implemented or would consider patches for. By doing so, we can make it easier for potential contributors to Ruby to easily see possible contributions they could make.</p>
<p>I've added a pull request with a draft of the proposed guide: <a href="https://github.com/ruby/ruby/pull/4953" class="external">https://github.com/ruby/ruby/pull/4953</a></p> Ruby master - Misc #18150 (Open): Proposal: Deprecate leading zero syntax to declare octals, sinc...https://bugs.ruby-lang.org/issues/181502021-09-03T17:10:05ZProGM (Piero Dotti)
<p>Hi there,<br>
I'd like to open a discussion about the leading zeros syntax to declare octal numbers.</p>
<p>Let me give you a little bit of context.</p>
<p>It seems like ruby considers all integers with leading zeros as octal.<br>
For instance, if you write 012, ruby reads it as 10 in decimal.<br>
There is an alternative syntax for this, using an "o" character after the zero, i.e. 0o12</p>
<p>I've discovered this behavior by chance a couple of days ago.<br>
I was declaring a new Date object:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">START_DATE</span> <span class="o">=</span> <span class="no">Date</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">2021</span><span class="p">,</span> <span class="mi">09</span><span class="p">,</span> <span class="mo">01</span><span class="p">)</span>
</code></pre>
<p>In my mind, I was thinking of ISO 8601 ("2021-09-01") and I wrote it in that way without even thinking about it.</p>
<p>I immediately got a weird error:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">SyntaxError</span> <span class="p">((</span><span class="n">irb</span><span class="p">):</span><span class="mi">2</span><span class="p">:</span> <span class="no">Invalid</span> <span class="n">octal</span> <span class="n">digit</span><span class="p">)</span>
</code></pre>
<p>That was astonishing. "What the heck does this error mean?", I thought.</p>
<p>After a brief research, I've discovered that many languages that come from C have this "weird" behavior.<br>
Javascript, Go, Java, and ruby itself all treat leading zeros like this.<br>
Rust and Elixir, instead, are parsing 00123 like 123, as math notation suggests.<br>
Finally, Python 3+ raises an error.</p>
<hr>
<p>My proposal is: throw a deprecation warning in ruby 3.x when using this syntax and treat 0011 as 11 from ruby 4+.</p>
<p>Why?</p>
<ul>
<li>Because it's extremely confusing</li>
<li>There is an alternative syntax that is much more explicit (0o11 vs 011)</li>
<li>It leads to weird behaviors (like 011 != 11)</li>
<li>Because Python 2.x was treating leading zeros numbers as octals like ruby does, but this has been changed in python 3+: <a href="https://medium.com/techmacademy/leading-zeros-in-python-a-hidden-mystery-revealed-ee3e3065634d" class="external">https://medium.com/techmacademy/leading-zeros-in-python-a-hidden-mystery-revealed-ee3e3065634d</a>
</li>
</ul>
<p>Ruby's claim is "A PROGRAMMER'S BEST FRIEND". As a programmer, I don't consider this behavior very friendly. :(</p>
<p>Let me know what you think about this!</p> Ruby master - Misc #18082 (Open): FileUtils.remove_entry_secure has inconsistent documenthttps://bugs.ruby-lang.org/issues/180822021-08-17T16:26:38Zpocke (Masataka Kuwabara)
<p><code>FileUtils.remove_entry_secure</code> and <code>FileUtils.rm_r</code> have inconsistency about the vulnerability condition the in the documentations.</p>
<p><code>remove_entry_secure</code> document:<br>
<a href="https://github.com/ruby/ruby/blob/6a9bfa4d9387b9d8f07f43f4546437be57f9e27c/lib/fileutils.rb#L660-L664" class="external">https://github.com/ruby/ruby/blob/6a9bfa4d9387b9d8f07f43f4546437be57f9e27c/lib/fileutils.rb#L660-L664</a></p>
<blockquote>
<p>#rm_r causes security hole when:</p>
<ul>
<li>Parent directory is world writable (including /tmp).</li>
<li>Removing directory tree includes world writable directory.</li>
<li>The system has symbolic link.</li>
</ul>
</blockquote>
<p><code>rm_r</code> document:<br>
<a href="https://github.com/ruby/ruby/blob/6a9bfa4d9387b9d8f07f43f4546437be57f9e27c/lib/fileutils.rb#L614-L618" class="external">https://github.com/ruby/ruby/blob/6a9bfa4d9387b9d8f07f43f4546437be57f9e27c/lib/fileutils.rb#L614-L618</a></p>
<blockquote>
<p>WARNING: This method causes local vulnerability<br>
if one of parent directories or removing directory tree are world<br>
writable (including /tmp, whose permission is 1777), and the current<br>
process has strong privilege such as Unix super user (root), and the<br>
system has symbolic link.</p>
</blockquote>
<p>The differences are following.</p>
<ul>
<li>
<code>rm_r</code> describes about strong privilege, but <code>remove_entry_secure</code> doesn't.</li>
<li>
<code>rm_r</code> describes "one of parent directories <strong>OR</strong> removing directory tree are world writable", but the conditions are just listed in <code>remove_entry_secure</code> doc, it seems <strong>AND</strong> condition.</li>
</ul>
<p>I couldn't understand the prerequisites of the vulnerability from the documents.<br>
I think both documents should describe the same prerequisites.</p>
<p>I don't know what is the right prerequisites, so I didn't make a patch.</p> Ruby master - Misc #17829 (Open): Clang/LLVM correctness of x64-mingw32 build (`shorten-64-to-32`...https://bugs.ruby-lang.org/issues/178292021-04-26T16:23:26Zxtkoba (Tee KOBAYASHI)
<p>The attached log is from <code>make miniruby</code> for x64-mingw32 with Clang/LLVM. Warnings are silenced except for <code>-Wshorten-64-to-32</code>.</p>
<p>This might not be an issue solely for Clang/LLVM, because the size of each type is the same as that in GCC.</p>
<p>I believe most of them are false positive. It would be easy to silence these warnings by explicit type casting. But before doing so, it must be checked whether each shortening is legitimate or not.</p>
<p>Version: <code>ruby 3.1.0dev (2021-04-26T13:46:51Z master 203eeeefdd) [x64-mingw32]</code></p> Ruby master - Misc #17683 (Open): Current status of beginless range (experimental or not)https://bugs.ruby-lang.org/issues/176832021-03-10T09:40:02Zjnchito (Junichi Ito)
<p>A beginless range was experimentally introduced in Ruby 2.7.0:<br>
<a href="https://github.com/ruby/ruby/blob/v2_7_0/NEWS#label-Other+miscellaneous+changes" class="external">https://github.com/ruby/ruby/blob/v2_7_0/NEWS#label-Other+miscellaneous+changes</a></p>
<p>Is it still experimental feature or not?</p> Ruby master - Misc #17637 (Open): Endless ranges with `nil` boundary weird behaviorhttps://bugs.ruby-lang.org/issues/176372021-02-17T10:49:17Zgud (gud gud)
<p>Basically it's about this <a href="https://andycroll.com/ruby/watch-out-for-nils-in-ranges/" class="external">https://andycroll.com/ruby/watch-out-for-nils-in-ranges/</a></p>
<p>Since Ruby 2.6 we have this weird syntax (0..nil) which is really really bug prone</p>
<p>e.g. we have dynamic upper boundary like</p>
<pre><code>lower = 0
upper = some_method(arg1, arg2)
(lower..upper).each do { |s| some_method2(s) }
</code></pre>
<p>We rarely do <code>nil</code> checks in Ruby so it's really easy to have Infinity loop in the end.<br>
Previous Argument error was more intuitive since it throws exception instead of silently looping forever.</p>
<ul>
<li>some additional strange behavior:</li>
</ul>
<pre><code>(0..nil).count
=> Infinity
(0..Float::INFINITY).count
=> hangs, I guess same infinity loop
</code></pre>
<p>Having explicit parameter <code>Float::INFINITY</code> (as in previous versions) looks more like a proper design instead of allowing <code>nil</code> as a valid parameter.</p>
<p>You may think of it as <strong>I would like to have a range from 0 to nothing, what is it actually ?</strong><br>
And I guess the answer is <strong>Nothing</strong>.<br>
Fixing <code>(0..Float::INFINITY).count</code> this case it also important I believe.</p>
<p>Tested on <code>ruby 2.7.1p83</code></p> Ruby master - Misc #17586 (Open): Please run Windows CI in all std-lib reposhttps://bugs.ruby-lang.org/issues/175862021-01-27T17:40:41ZMSP-Greg (Greg L)
<p>Please consider adding Windows CI to all std-lib repos.</p>
<p>Having ruby/ruby CI fail due to std-lib commits merged from their respective repos causes downstream issues, wasted time, etc.</p>
<p>See <a href="https://github.com/ruby/irb/pull/179" class="external">https://github.com/ruby/irb/pull/179</a> for an example adding Windows to Actions CI.</p>
<p>Re Actions matrix:</p>
<ol>
<li>The os change from <code>*-latest</code> to <code>*-<numeric></code> (eg, <code>macos-latest</code> to <code>macos-11.0</code>). The <code>-latest</code> designation changes, so some may prefer a <code>-<numeric></code> tag. See <a href="https://github.com/actions/virtual-environments#available-environments" class="external">https://github.com/actions/virtual-environments#available-environments</a> for available environments and their naming.</li>
<li>Using numeric versions for Ruby causes an issue with 3.0, as it’s interpreted as 3, which is only a sematic major requirement. Hence, quote all numeric versions.</li>
</ol> Ruby master - Misc #17565 (Open): Prefer use of access(2) in rb_file_load_ok() to check for exist...https://bugs.ruby-lang.org/issues/175652021-01-20T20:05:56Zleehambley (Lee Hambley)
<p>When using Ruby in Docker (2.5 in our case, but the code is unchanged in 15 years across all versions) with a large $LOAD_PATH some millions of calls are made to <code>open(2)</code> with a mean cost of 130µsec per call, where a call to <code>access(2)</code> has a cost around 5× lower (something around 28µsec).</p>
<p>With a Rails 5 app, without Zeitwerk, the load path is searched iteratively looking for a file to define a constant, this causes something like 2,000,000 calls to <code>open(2)</code> of which 97.5% are failing with <code>ENOENT</code>.</p>
<p>I believe that the cost of two syscalls (<code>open(2)</code> only after successful <code>access(2)</code>) would, in our case, at least because we would shave-off something like 1,900,000×90µsec (2.85 minutes) from the three minute boot time for our application.</p>
<p>I prepared a very naïve patch with a simple early-return in <code>rb_file_load_ok</code>:</p>
<pre><code>diff --git a/file.c b/file.c
index 3bf092c05c..c7a7635125 100644
--- a/file.c
+++ b/file.c
@@ -5986,6 +5986,16 @@ rb_file_load_ok(const char *path)
O_NDELAY |
#endif
0);
+ if (access(path, R_OK) == -1) return 0;
int fd = rb_cloexec_open(path, mode, 0);
if (fd == -1) return 0;
rb_update_max_fd(fd);
</code></pre>
<p>This hasn't been exhaustively tested as I simply haven't had time yet, but at least it compiled and passed <code>make check</code>.</p>
<p>I spoke with Aaron Patterson on Twitter, who suggested maybe a wiser approach would be a heuristic approach one level higher (<code>rb_find_file</code>?) which switches the strategy based on the length of the LOAD_PATH.</p>
<p>Alternatively, maybe the patch could be conditional, guarded somehow, and conditionally compiled only into the Rubies built for Docker, in a way that is portable to the common Ruby version managers.</p>
<p>I am opening this ticket to track my own work, as much as anything, with no expectation that someone implement this on my behalf. I am eager to contribute to Ruby for all the benefit I have seen from it in my career.</p>
<p>If someone knows hints why this may be an unsuccessful adventure, I gratefully receive any and all feedback.</p> Ruby master - Misc #17337 (Open): Don't embed Ruby build-time configuration in Rubyhttps://bugs.ruby-lang.org/issues/173372020-11-20T09:49:55Zvo.x (Vit Ondruch)v.ondruch@tiscali.cz
<p>When Ruby 3.0 is built without C++ compiler available, subsequent builds of Eventmachine extensions (or any other gems that require C++ compiler) fail:</p>
<pre><code>... snip ...
"make \"DESTDIR=\""
I. -I/usr/include -I/usr/include/ruby/backward -I/usr/include -I. -DHAVE_OPENSSL_SSL_H -DHAVE_OPENSSL_ERR_H -DWITH_SSL -DBUILD_FOR_RUBY -DHAVE_RB_THREAD_CALL_WITHOUT_GVL -DHAVE_RB_THREAD_FD_SELECT -DHAVE_TYPE_RB_FDSET_T -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_RB_TIME_NEW -DHAVE_INOTIFY_INIT -DHAVE_INOTIFY -DHAVE_WRITEV -DHAVE_PIPE2 -DHAVE_ACCEPT4 -DHAVE_CONST_SOCK_CLOEXEC -DOS_UNIX -DHAVE_EPOLL_CREATE -DHAVE_EPOLL -DHAVE_CLOCK_GETTIME -DHAVE_CONST_CLOCK_MONOTONIC_RAW -DHAVE_CONST_CLOCK_MONOTONIC -fPIC -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -m64 -o binder.o -c binder.cpp
make: I.: No such file or directory
make: [Makefile:237: binder.o] Error 127 (ignored)
</code></pre>
<p>This happens since <a href="https://github.com/ruby/ruby/commit/50b18e81295ad2d45975e4d8ea1e0c7e85140b97" class="external">1</a>.</p>
<p>I would like to question not just the commit, but the whole principle. Availability of C++ compiler during build of Ruby does not have anything to do with availability of C++ compiler during build of whatever Ruby extension.</p>
<p>Moreover, the machine where Ruby is built might be different from the machine where Ruby is used and the extension is installed. Typical examples are binary Linux distributions. RVM also uses precompiled Ruby binaries if I am not mistaken.</p>
<p>Therefore, I would appreciate if we reconsider embedding Ruby build-time configuration in Ruby and reusing it for Ruby extension build. This would solve the issue of Eventmachine I started with, and also issues such as <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Ruby configuration options should not be reused for gem builds (Closed)" href="https://bugs.ruby-lang.org/issues/14422">#14422</a></p>
<p>Just FTR, to avoid this kind of issues, as a Ruby maintainer on Red Hat platforms, I am considering to ship rbconfig.rb in vendorlib, which would dynamically fix these issues. E.g. set the <code>CONFIG['CXX']</code> based on C++ compiler availability during extension build. But I'd like to avoid it, at least as a downstream modification.</p> Ruby master - Misc #17309 (Open): URI.escape being deprecated, yet there is no replacementhttps://bugs.ruby-lang.org/issues/173092020-11-07T01:26:10Zchucke (Tiago Cardoso)
<p>I'm on ruby 2.7.2 . The moment I do</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">uri</span> <span class="o">=</span> <span class="s2">"http://bücher.ch"</span>
<span class="no">URI</span><span class="p">.</span><span class="nf">escape</span> <span class="n">uri</span>
<span class="p">(</span><span class="n">irb</span><span class="p">):</span><span class="mi">5</span><span class="p">:</span> <span class="ss">warning: </span><span class="no">URI</span><span class="p">.</span><span class="nf">escape</span>
<span class="s2">"http://b%C3%BCcher.ch"</span>
</code></pre>
<p>I get that warning. Rubocop also tells me:</p>
<p>"""<br>
URI.escape method is obsolete and should not be used. Instead, use CGI.escape, URI.encode_www_form or URI.encode_www_form_component depending on your specific use case.<br>
"""</p>
<p>However, none of the suggestions does the same as <code>URI.escape</code>.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">CGI</span><span class="p">.</span><span class="nf">escape</span> <span class="n">uri</span>
<span class="o">=></span> <span class="s2">"http%3A%2F%2Fb%C3%BCcher.ch"</span>
<span class="no">URI</span><span class="p">.</span><span class="nf">encode_www_form_component</span> <span class="n">uri</span>
<span class="o">=></span> <span class="s2">"http%3A%2F%2Fb%C3%BCcher.ch"</span>
<span class="no">URI</span><span class="p">.</span><span class="nf">encode_www_form</span> <span class="n">uri</span>
<span class="no">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="no">NoMethodError</span> <span class="p">(</span><span class="n">undefined</span> <span class="nb">method</span> <span class="sb">`map' for "http://bücher.ch":String)
Did you mean? tap
</span></code></pre>
<p>So my question is: why is this being deprecated? And if there's still reason, what to exactly replace it for, so I can keep the exact same behaviour?</p> Ruby master - Misc #17199 (Open): id outputed by inspect and to_s output does not allow to find a...https://bugs.ruby-lang.org/issues/171992020-09-28T11:40:39ZAnnih (Baptiste Courtois)
<p>Hello, here is my first ruby issue sorry in advance if it is incorrectly filled.</p>
<a name="Issue"></a>
<h1 >Issue<a href="#Issue" class="wiki-anchor">¶</a></h1>
<p>The value returned by <code>#object_id</code> is not aligned anymore with displayed info in <code>#inspect</code> and <code>#to_s</code> methods.</p>
<a name="with-ruby-lt-27"></a>
<h2 >with ruby < 2.7<a href="#with-ruby-lt-27" class="wiki-anchor">¶</a></h2>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Object</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">tap</span> <span class="p">{</span> <span class="o">|</span><span class="n">o</span><span class="o">|</span> <span class="nb">p</span> <span class="s2">"#to_s=</span><span class="si">#{</span><span class="n">o</span><span class="p">.</span><span class="nf">to_s</span><span class="si">}</span><span class="s2">, #inspect=</span><span class="si">#{</span><span class="n">o</span><span class="p">.</span><span class="nf">inspect</span><span class="si">}</span><span class="s2">, #__id__=</span><span class="si">#{</span><span class="n">o</span><span class="p">.</span><span class="nf">__id__</span><span class="si">}</span><span class="s2">, shifted_id=</span><span class="si">#{</span><span class="p">(</span><span class="n">o</span><span class="p">.</span><span class="nf">__id__</span> <span class="o"><<</span> <span class="mi">1</span><span class="p">).</span><span class="nf">to_s</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span> <span class="p">}</span>
<span class="s2">"#to_s=#<Object:0x0000000000d202a8>, #inspect=#<Object:0x0000000000d202a8>, #__id__=6881620, shifted_id=d202a8"</span>
</code></pre>
<a name="with-ruby-gt-27"></a>
<h2 >with ruby >= 2.7<a href="#with-ruby-gt-27" class="wiki-anchor">¶</a></h2>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="no">Object</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">tap</span> <span class="p">{</span> <span class="o">|</span><span class="n">o</span><span class="o">|</span> <span class="nb">p</span> <span class="s2">"#to_s=</span><span class="si">#{</span><span class="n">o</span><span class="p">.</span><span class="nf">to_s</span><span class="si">}</span><span class="s2">, #inspect=</span><span class="si">#{</span><span class="n">o</span><span class="p">.</span><span class="nf">inspect</span><span class="si">}</span><span class="s2">, #__id__=</span><span class="si">#{</span><span class="n">o</span><span class="p">.</span><span class="nf">__id__</span><span class="si">}</span><span class="s2">, shifted_id=</span><span class="si">#{</span><span class="p">(</span><span class="n">o</span><span class="p">.</span><span class="nf">__id__</span> <span class="o"><<</span> <span class="mi">1</span><span class="p">).</span><span class="nf">to</span>
<span class="n">s</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span> <span class="p">}</span>
<span class="s2">"#to_s=#<Object:0x0000555dc8640b88>, #inspect=#<Object:0x0000555dc8640b88>, #__id__=220, shifted_id=1b8"</span>
</code></pre>
<a name="Consequences"></a>
<h1 >Consequences<a href="#Consequences" class="wiki-anchor">¶</a></h1>
<p>It makes harder:</p>
<ul>
<li>to implement a clean override of the <code>#inspect</code> method. i.e. How to keep the same output without ability to compute to the same "object_id" value.</li>
<li>to debug the object using the inspect output. i.e. <code>ObjectSpace._id2ref(id_from_inspect >> 1)</code> used to work, now it doesn't (<code>RangeError: <xXx> is not id value</code>).</li>
</ul>
<a name="Suggestion"></a>
<h1 >Suggestion<a href="#Suggestion" class="wiki-anchor">¶</a></h1>
<p>IMHO either:</p>
<ul>
<li>the <code>#to_s</code> and <code>#inspect</code> documentation are obsolete <code>The default [...] [shows|prints] [...] an encoding of the object id</code> and the change could have been a bit more advertised</li>
<li>they should use the result of <code>#object_id</code> instead of displaying the object pointer address</li>
</ul>
<p>Another solution could be to provide a method to get access to the address, but I'm not sure you want that.</p>
<p>P.S. While debugging my problem I found <a href="https://www.ruby-forum.com/t/understanding-object-id-in-ruby-2-7/260268/4" class="external">this ruby-forum thread</a> where people dived a bit more than me into ruby's code.</p> Ruby master - Misc #17180 (Open): Ractor and constant referencinghttps://bugs.ruby-lang.org/issues/171802020-09-19T21:24:45Zkirs (Kir Shatrov)shatrov@me.com
<p>Hey there.</p>
<p>From a high level, this bug report is describing my experience building something simple with Ractor without any shared state. I hope this is helpful as a feedback for the stable Ractor implementation in Ruby 3.0.</p>
<p>I've been iterating on a simple web server that utilizes Ractor. One of the things that a web server does is parsing HTTP headers. Thankfully, there's code in Ruby's standard library that can do that, so I decided to leverage <code>WEBrick::HTTPRequest</code>.</p>
<p>Here's my example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'webrick'</span>
<span class="nb">require</span> <span class="s1">'stringio'</span>
<span class="n">parser</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">s</span> <span class="o">=</span> <span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"GET / HTTP/1.1</span><span class="se">\n</span><span class="s2">"</span><span class="p">\</span>
<span class="s2">"Host: example.com</span><span class="se">\n</span><span class="s2">"</span><span class="p">\</span>
<span class="s2">"User-Agent: curl/7.64.1</span><span class="se">\n</span><span class="s2">"</span><span class="p">\</span>
<span class="s2">"Accept: */*"</span><span class="p">)</span>
<span class="n">req</span> <span class="o">=</span> <span class="no">WEBrick</span><span class="o">::</span><span class="no">HTTPRequest</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">WEBrick</span><span class="o">::</span><span class="no">Config</span><span class="o">::</span><span class="no">HTTP</span><span class="p">)</span>
<span class="n">req</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="k">end</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">select</span><span class="p">(</span><span class="n">parser</span><span class="p">)</span>
</code></pre>
<p>This fails with <code>can not access non-sharable objects in constant WEBrick::Config::HTTP by non-main Ractor. (NameError)</code>.</p>
<p>Let's try to copy that constant and pass it to the Ractor:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'webrick'</span>
<span class="nb">require</span> <span class="s1">'stringio'</span>
<span class="n">parser</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">WEBrick</span><span class="o">::</span><span class="no">Config</span><span class="o">::</span><span class="no">HTTP</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">config</span><span class="o">|</span>
<span class="n">s</span> <span class="o">=</span> <span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"GET / HTTP/1.1</span><span class="se">\n</span><span class="s2">"</span><span class="p">\</span>
<span class="s2">"Host: example.com</span><span class="se">\n</span><span class="s2">"</span><span class="p">\</span>
<span class="s2">"User-Agent: curl/7.64.1</span><span class="se">\n</span><span class="s2">"</span><span class="p">\</span>
<span class="s2">"Accept: */*"</span><span class="p">)</span>
<span class="n">req</span> <span class="o">=</span> <span class="no">WEBrick</span><span class="o">::</span><span class="no">HTTPRequest</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">config</span><span class="p">)</span>
<span class="n">req</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="k">end</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">select</span><span class="p">(</span><span class="n">parser</span><span class="p">)</span>
</code></pre>
<p>This failed with <code>can't dump hash with default proc</code>. I've guessed that maybe <code>WEBrick::Config::HTTP</code> has a default proc? Let's try to work around:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'webrick'</span>
<span class="nb">require</span> <span class="s1">'stringio'</span>
<span class="n">http_c</span> <span class="o">=</span> <span class="no">WEBrick</span><span class="o">::</span><span class="no">Config</span><span class="o">::</span><span class="no">HTTP</span>
<span class="n">http_c</span><span class="p">.</span><span class="nf">default</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="n">parser</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">http_c</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">config</span><span class="o">|</span>
<span class="n">s</span> <span class="o">=</span> <span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"GET / HTTP/1.1</span><span class="se">\n</span><span class="s2">"</span><span class="p">\</span>
<span class="s2">"Host: example.com</span><span class="se">\n</span><span class="s2">"</span><span class="p">\</span>
<span class="s2">"User-Agent: curl/7.64.1</span><span class="se">\n</span><span class="s2">"</span><span class="p">\</span>
<span class="s2">"Accept: */*"</span><span class="p">)</span>
<span class="n">req</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="k">end</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">select</span><span class="p">(</span><span class="n">parser</span><span class="p">)</span>
</code></pre>
<p>It failed with:</p>
<pre><code>/Users/kir/src/github.com/ruby/ruby/lib/webrick/httprequest.rb:570:in `read_line': can not access non-sharable objects in constant WEBrick::LF by non-main ractor. (NameError)
</code></pre>
<p>I went ahead and made WEBrick freeze strings:</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/lib/webrick/httputils.rb b/lib/webrick/httputils.rb
index 76d4bd0dc7..273c596368 100644
</span><span class="gd">--- a/lib/webrick/httputils.rb
</span><span class="gi">+++ b/lib/webrick/httputils.rb
</span><span class="p">@@ -13,9 +13,9 @@</span>
require 'tempfile'
<span class="err">
</span> module WEBrick
<span class="gd">- CR = "\x0d" # :nodoc:
- LF = "\x0a" # :nodoc:
- CRLF = "\x0d\x0a" # :nodoc:
</span><span class="gi">+ CR = "\x0d".freeze # :nodoc:
+ LF = "\x0a".freeze # :nodoc:
+ CRLF = "\x0d\x0a".freeze # :nodoc:
</span><span class="err">
</span></code></pre>
<p>Now it's failing with:</p>
<pre><code>/Users/kir/src/github.com/ruby/ruby/lib/singleton.rb:124:in `instance': can not access instance variables of classes/modules from non-main Ractors (RuntimeError)
from /Users/kir/src/github.com/ruby/ruby/lib/webrick/utils.rb:132:in `register'
from /Users/kir/src/github.com/ruby/ruby/lib/webrick/utils.rb:256:in `timeout'
from /Users/kir/src/github.com/ruby/ruby/lib/webrick/httprequest.rb:559:in `_read_data'
from /Users/kir/src/github.com/ruby/ruby/lib/webrick/httprequest.rb:570:in `read_line'
from /Users/kir/src/github.com/ruby/ruby/lib/webrick/httprequest.rb:447:in `read_request_line'
from /Users/kir/src/github.com/ruby/ruby/lib/webrick/httprequest.rb:201:in `parse'
from ./test.rb:16:in `block in <main>'
</code></pre>
<p>because WEBrick is manipulating with a class variable.</p>
<p>I've commented out some of that code in WEBrick for the sake of experiment and it started to fail with:</p>
<pre><code>/Users/kir/src/github.com/ruby/ruby/lib/uri/common.rb:171:in `parse': can not access non-sharable objects in constant URI::RFC3986_PARSER by non-main ractor. (NameError)
from /Users/kir/src/github.com/ruby/ruby/lib/webrick/httprequest.rb:484:in `parse_uri'
from /Users/kir/src/github.com/ruby/ruby/lib/webrick/httprequest.rb:217:in `parse'
</code></pre>
<p>This can be easily reproduced with a smaller piece of code:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">parser</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="no">URI</span><span class="o">::</span><span class="n">parse</span><span class="p">(</span><span class="s2">"http://example.com"</span><span class="p">)</span>
<span class="k">end</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">select</span><span class="p">(</span><span class="n">parser</span><span class="p">)</span>
</code></pre>
<hr>
<p>IMO, something as tiny and safe as <code>URI::parse</code> should be allowrd to be called from a Ractor. We're either being too strict to the developer in terms of what constants they can reference from inside a Ractor, or we're missing a bunch of <code>freeze</code> in the standard library. It's likely the latter, but in that case we'll need to push for <code>freeze</code> as much as we can to make Ractor friendly to developers.</p>
<p>I'm very excited to see this happening in Ruby 3.0 and I'd like to help as much as I can to make it a great feature of Ruby.</p> Ruby master - Misc #17174 (Open): "Error relocating, symbol not found" error when compiling a nat...https://bugs.ruby-lang.org/issues/171742020-09-16T05:29:49ZNakilon (Victor Maslov)nakilon@gmail.com
<p>My native extension gem compiles fine with all versions of Ruby on macOS but only with Ruby 2.3 on Alpine. It throws various <code>Error relocating</code>, <code>symbol not found</code> when I require the <code>.o</code> file. Here I made a branch to reproduce it in Docker quickly.</p>
<pre><code>git clone https://github.com/Nakilon/dhash-vips.git --branch alpine-compilation-issues alpine-compilation-issues && cd alpine-compilation-issues
</code></pre>
<pre><code># compiles and does not fail on require
docker build - -t temp-ruby2.3.8 --build-arg RUBY_VERSION=2.3.8 --build-arg ALPINE_VERSION=3.8 <Dockerfile
# Error relocating /dhash-vips/idhash.so: rb_deprecate_constant: symbol not found - /dhash-vips/idhash.so (LoadError)
docker build - -t temp-ruby2.4.10 --build-arg RUBY_VERSION=2.4.10 --build-arg ALPINE_VERSION=3.11 <Dockerfile
# Error relocating /dhash-vips/idhash.so: rb_int_modulo: symbol not found - /dhash-vips/idhash.so (LoadError)
docker build - -t temp-ruby2.5.8 --build-arg RUBY_VERSION=2.5.8 --build-arg ALPINE_VERSION=3.12 <Dockerfile
# Error relocating /dhash-vips/idhash.so: rb_int_pow: symbol not found - /dhash-vips/idhash.so (LoadError)
docker build - -t temp-ruby2.6.6 --build-arg RUBY_VERSION=2.6.6 --build-arg ALPINE_VERSION=3.12 <Dockerfile
</code></pre>
<p>I wanted to ask in the Mailing List but for some reason my email didn't reach it. Guy on Freenode recommended to post here.</p> Ruby master - Misc #17053 (Open): RDoc for Hash Keyshttps://bugs.ruby-lang.org/issues/170532020-07-27T15:42:50Zburdettelamar@yahoo.com (Burdette Lamar)burdettelamar@example.com
<p>marcandre <a href="https://github.com/ruby/ruby/pull/3139#issuecomment-663281047" class="external">comments</a> on my pull request regarding <a href="https://docs.ruby-lang.org/en/master/Hash.html#class-Hash-label-Hash+Keys" class="external">documentation of Hash in Rdoc</a>:</p>
<blockquote>
<p>The only thing I would change is that I would shorten the doc on the "Invalid Hash Keys". As far as I know, this is simply not a[n] important concern as nearly all Ruby objects respond_to? :hash and :eql?</p>
</blockquote>
<blockquote>
<p>I personally would recommend adding a single example in the Hash.html#class-Hash-label-Hash+Keys section and I would remove the rest, or at least remove the examples. They burden the reader with something that is of no use to them.</p>
</blockquote>
<p>I have misgivings about it:</p>
<ul>
<li>Some of the material, for example, the text and example for user-defined hash keys, is very old.</li>
<li>I consolidated some material from earlier doc for individual methods, which now link to the relevant sections.</li>
<li>All are factual and not repeated elsewhere in the page.</li>
</ul>
<p>This is an API reference documentation. Ruby should have a <em>reference documentation</em>, and therefore should not omit anything.</p>
<p>If such material is to be included, I see three possibilities:</p>
<ul>
<li>Include inline, as is now.</li>
<li>Link to a footnote on the same page, with a back link.</li>
<li>Link to another rdoc page in <code>doc/</code> dir.</li>
</ul>
<p>I'd love to hear some opinions on this.</p> Ruby master - Misc #16895 (Open): Request for cooperation: Try your applications/libraries with m...https://bugs.ruby-lang.org/issues/168952020-05-15T09:13:23Zko1 (Koichi Sasada)
<a name="Summary"></a>
<h2 >Summary<a href="#Summary" class="wiki-anchor">¶</a></h2>
<p>If you maintain a Ruby application or library, please consider testing with the Ruby <code>master</code> branch, including the <em>debug</em> build. This should be in addition to testing with all supported stable releases of Ruby.</p>
<p>To make this easier, we are providing Docker images and GitHub actions, as outlined below.</p>
<a name="Details"></a>
<h2 >Details<a href="#Details" class="wiki-anchor">¶</a></h2>
<p>The rapid pace of Ruby development sometimes introduces bugs, such as incorrect behaviour or unexpected incompatibilities. Despite our best efforts and testing, without your feedback, we cannot catch every issue.</p>
<p>Understanding how our changes impact downstream code is important feedback for the Ruby core developers. We want to know how your applications work on master.</p>
<p>If you encounter an error when testing with the <code>master</code> branch (e.g. <code>[BUG] ...</code> in output log), <a href="https://bugs.ruby-lang.org" class="external">please report it</a>. It will be very helpful.</p>
<h3>Testing With <code>master</code>
</h3>
<p>Testing using the <code>master</code> branch (sometimes referred to as <code>ruby-head</code>) will make your Ruby scripts ready for the next Ruby version. It also helps us catch incompatibilities as we change and evolve Ruby's public interface.</p>
<a name="Testing-With-Debug-Build"></a>
<h3 >Testing With Debug Build<a href="#Testing-With-Debug-Build" class="wiki-anchor">¶</a></h3>
<p>Testing with the master branch debug build enables many assertions within the Ruby interpreter.</p>
<p>These assertions can detect incorrect usage of the C extensions, and also bugs in the interpreter when running your program.</p>
<p>These assertions have an impact on the performance of the interpreter.</p>
<p>To compile a debug build, refer the later section titled "Building With Debug Mode".</p>
<h2>Continuous Integration With <code>master</code>
</h2>
<p>Building Ruby for your own testing environment can be difficult, so we are providing two convenient ways to use the master branch in your existing testing pipeline:</p>
<ul>
<li>Docker Images</li>
<li>Github Action</li>
</ul>
<a name="Docker-Images"></a>
<h3 >Docker Images<a href="#Docker-Images" class="wiki-anchor">¶</a></h3>
<p>The <a href="https://hub.docker.com/r/rubylang/ruby" class="external">rubylang docker repository</a> provides images for various Ruby versions, including nightly builds of master with and without debug assertions"</p>
<ul>
<li>Nightly built master: <code>rubylang/ruby:master-nightly-bionic</code>
</li>
<li>Nightly debug built master: <code>rubylang/ruby:master-debug-nightly-bionic</code>
</li>
</ul>
<p>Here is an example <code>Dockerfile</code>:</p>
<pre><code class="dockerfile syntaxhl" data-language="dockerfile"><span class="k">FROM</span><span class="s"> rubylang/ruby:master-nightly-bionic</span>
</code></pre>
<p>Then to build:</p>
<pre><code class="shell syntaxhl" data-language="shell"><span class="nv">$ </span>docker build <span class="nb">.</span>
Sending build context to Docker daemon 2.048kB
Step 1/1 : FROM rubylang/ruby:master-nightly-bionic
master-nightly-bionic: Pulling from rubylang/ruby
...
Status: Downloaded newer image <span class="k">for </span>rubylang/ruby:master-nightly-bionic
<span class="nt">---</span><span class="o">></span> 059d367a8fbd
Successfully built 059d367a8fbd
</code></pre>
<a name="GitHub-Action"></a>
<h3 >GitHub Action<a href="#GitHub-Action" class="wiki-anchor">¶</a></h3>
<p>The <a href="https://github.com/ruby/setup-ruby" class="external">GitHub Action to setup Ruby</a> provides both <code>ruby-head</code> and <code>ruby-debug</code> builds.</p>
<p>Here is an example workflow to test on all Ruby stable releases, including <code>ruby-head</code> and <code>ruby-debug</code>:</p>
<pre><code class="yaml syntaxhl" data-language="yaml"><span class="na">name</span><span class="pi">:</span> <span class="s">Development</span>
<span class="na">on</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">push</span><span class="pi">]</span>
<span class="na">jobs</span><span class="pi">:</span>
<span class="na">test</span><span class="pi">:</span>
<span class="na">strategy</span><span class="pi">:</span>
<span class="na">fail-fast</span><span class="pi">:</span> <span class="kc">false</span>
<span class="na">matrix</span><span class="pi">:</span>
<span class="na">os</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">ubuntu</span><span class="pi">]</span>
<span class="na">ruby</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">2.5</span><span class="pi">,</span> <span class="nv">2.6</span><span class="pi">,</span> <span class="nv">2.7</span><span class="pi">,</span> <span class="nv">head</span><span class="pi">,</span> <span class="nv">debug</span><span class="pi">]</span>
<span class="na">runs-on</span><span class="pi">:</span> <span class="s">${{ matrix.os }}-latest</span>
<span class="na">continue-on-error</span><span class="pi">:</span> <span class="s">${{ matrix.ruby == 'head' || matrix.ruby == 'debug' }}</span>
<span class="na">steps</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span>
<span class="pi">-</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">ruby/setup-ruby@v1</span>
<span class="na">with</span><span class="pi">:</span>
<span class="na">ruby-version</span><span class="pi">:</span> <span class="s">${{ matrix.ruby }}</span>
<span class="pi">-</span> <span class="na">run</span><span class="pi">:</span> <span class="s">bundle install</span>
<span class="pi">-</span> <span class="na">run</span><span class="pi">:</span> <span class="s">bundle exec rake</span>
</code></pre>
<p>See the <a href="https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby" class="external">documentation</a> for more details on how to use this action.</p>
<a name="Building-With-Debug-Mode"></a>
<h2 >Building With Debug Mode<a href="#Building-With-Debug-Mode" class="wiki-anchor">¶</a></h2>
<p>To create a debug build of Ruby, execute the following commands:</p>
<pre><code>$ git clone https://github.com/ruby/ruby.git
$ cd ruby
$ autoconf
$ cppflags=-DRUBY_DEBUG=1 ./configure --prefix=$HOME/.rubies/ruby-debug
$ make install
</code></pre>
<p>If you are using <code>chruby</code>, you can switch to the above build:</p>
<pre><code>$ chruby ruby-debug
</code></pre>
<p>You can find more details to build Ruby master in the <a href="https://github.com/ruby/ruby/blob/master/README.md#how-to-compile-and-install" class="external">README</a>.</p>
<a name="Acknowledgement"></a>
<h2 >Acknowledgement<a href="#Acknowledgement" class="wiki-anchor">¶</a></h2>
<p>We thank <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/482">@mrkn (Kenta Murata)</a> for the Docker image, <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/772">@Eregon (Benoit Daloze)</a> for the GitHub Action, and <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/3344">@ioquatix (Samuel Williams)</a> for reviewing this announcement.</p> Ruby master - Misc #16803 (Open): Discussion: those internal macros reside in public API headershttps://bugs.ruby-lang.org/issues/168032020-04-21T07:45:49Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<p>A while ago I merged <a href="https://github.com/ruby/ruby/pull/2991" class="external">https://github.com/ruby/ruby/pull/2991</a> ("Split ruby.h"). This seems working. But the changeset raised several questions.</p>
<p>The biggest one relates to those newly publicised macros and inline functions. For instance <code>RUBY3_STATIC_ASSERT</code> is a macro that expands to either <code>_Static_assert</code> (for C) or <code>static_assert</code> (for C++). A similar mechanism has been implemented inside of our repository for a while. The pull request moved the definition around to be visible outside.</p>
<a name="Discussion-1"></a>
<h4 >Discussion #1<a href="#Discussion-1" class="wiki-anchor">¶</a></h4>
<p>Is it a good idea or a bad idea, to make them visible worldwide?</p>
<a name="Discussion-2"></a>
<h4 >Discussion #2<a href="#Discussion-2" class="wiki-anchor">¶</a></h4>
<p>Why not publicise everything? For instance debuggers could benefit from ruby internal symbols.</p>
<a name="Discussion-3"></a>
<h4 >Discussion #3<a href="#Discussion-3" class="wiki-anchor">¶</a></h4>
<p>It is relatively hard for us to change public APIs (doing so could break 3rd party gems). We don't want that happen for internal APIs. How do we achieve future flexibility?</p> Ruby master - Misc #16750 (Open): Change typedef of VALUE for better type checkinghttps://bugs.ruby-lang.org/issues/167502020-04-01T18:22:10ZDan0042 (Daniel DeLorme)
<p>VALUE is currently defined as <code>typedef unsigned long VALUE</code>, but as we all know that only creates an <em>alias</em>, not an actual <em>type</em>. Since the compiler gives no warnings when comparing with other integer values, it's easy to have bugs such as <code>v == 42</code> which should have been <code>v == INT2FIX(42)</code>. Actually not so long ago I saw nobu fixing a bug of that kind where an ID had been mixed up with a VALUE.</p>
<p>So in order to prevent these kinds of bugs I propose changing VALUE to a non-scalar type such as:</p>
<pre><code class="c syntaxhl" data-language="c"><span class="c1">//example for 64-bit system</span>
<span class="k">typedef</span> <span class="k">union</span> <span class="n">VALUE</span> <span class="p">{</span>
<span class="k">struct</span> <span class="n">RBasic</span><span class="o">*</span> <span class="n">as_basic</span><span class="p">;</span> <span class="c1">//easy access to obj.as_basic->klass and obj.as_basic->flags</span>
<span class="kt">void</span><span class="o">*</span> <span class="n">as_ptr</span><span class="p">;</span> <span class="c1">//can assign ptr = obj.as_ptr without a cast</span>
<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">i</span><span class="p">;</span> <span class="c1">//raw int value for bitwise operations</span>
<span class="kt">int</span> <span class="n">immediate</span> <span class="o">:</span> <span class="mi">3</span><span class="p">;</span> <span class="c1">//obj.immediate != 0 if obj is immediate type such as fixnum, flonum, static symbol</span>
<span class="kt">int</span> <span class="n">is_fixnum</span> <span class="o">:</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">//obj.is_fixnum == 1 if obj is fixnum</span>
<span class="k">struct</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">flag</span> <span class="o">:</span> <span class="mi">2</span><span class="p">;</span> <span class="c1">//obj.flonum.flag == 2 if obj is flonum</span>
<span class="kt">int</span> <span class="n">bits</span> <span class="o">:</span> <span class="mi">62</span><span class="p">;</span>
<span class="p">}</span> <span class="n">flonum</span><span class="p">;</span>
<span class="k">struct</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">flag</span> <span class="o">:</span> <span class="mi">8</span><span class="p">;</span> <span class="c1">//obj.symbol.flag == 0x0c if obj is a static symbol</span>
<span class="kt">int</span> <span class="n">id</span> <span class="o">:</span> <span class="mi">56</span><span class="p">;</span> <span class="c1">//-> obj.symbol.id == STATIC_SYM2ID(obj)</span>
<span class="p">}</span> <span class="n">symbol</span><span class="p">;</span>
<span class="p">}</span> <span class="n">VALUE</span><span class="p">;</span>
</code></pre>
<p>This will allow proper type-checking via the compiler.</p>
<p>A little-known fact, structs and unions can be passed (and returned) by value to functions; this 64-bit union has the same performance as a 64-bit int. This approach also allows to simplify code like <code>((struct RBasic*)obj)->flags</code> into the much more readable <code>obj.as_basic->flags</code>, and <code>FIXNUM_P(obj)</code> can be expressed directly as <code>obj.is_fixnum</code>. The only downside is that direct comparison of union variables is not possible, so you would need to use for example <code>obj.i == Qfalse.i</code></p>
<p>To summarize, stricter type-checking would eliminate an entire class of bugs, and I estimate this change would require modifications to <strong>no more than 14%</strong> of the codebase (62,213 lines). Very much worth it I believe.</p> Ruby master - Misc #16678 (Open): Array#values_at has unintuitive behavior when supplied a range ...https://bugs.ruby-lang.org/issues/166782020-03-07T06:21:48Zprajjwal (Prajjwal Singh)
<p>Consider the following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># frozen_string_literal: true</span>
<span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="mi">5</span><span class="p">).</span><span class="nf">to_a</span>
<span class="nb">p</span> <span class="n">a</span><span class="p">.</span><span class="nf">values_at</span><span class="p">(</span><span class="mi">3</span><span class="o">..</span><span class="mi">5</span><span class="p">)</span> <span class="c1"># => [4, 5, nil]</span>
<span class="nb">p</span> <span class="n">a</span><span class="p">.</span><span class="nf">values_at</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="o">..</span><span class="mi">3</span><span class="p">)</span> <span class="c1"># => []</span>
</code></pre>
<p>When the range begins with a negative <code>(-1, 0, 1, 2, 3)</code>, it returns an empty array, which surprised me because I was expecting <code>[1, 2, 3, 4]</code>.</p>
<p>The argument for this is that it cold be confusing to allow this because the index <code>-1</code> could refer to the last argument and it would be unintuitive to return an array <code>[5, 1, 2, 3, 4]</code> with jumbled values.</p>
<p>The argument against it is that it makes perfect sense to account for this case and return <code>[nil, 1, 2, 3, 4]</code>.</p>
<p>Opening a dialog to see what others think of this.</p> Ruby master - Misc #16659 (Open): Documentation on Regexp missing for absence pattern (?~pat)https://bugs.ruby-lang.org/issues/166592020-02-27T16:16:20Zsvoop (Sven Schwyn)svoop_he38hj327c@delirium.ch
<p>The absence pattern <code>(?~pat)</code> available since Ruby 2.4.1 is <a href="https://git.ruby-lang.org/ruby.git/tree/doc/regexp.rdoc" class="external">not yet documented on <code>Regexp</code></a> as of today.</p>
<p>(Found it by coincidence reading <a href="https://medium.com/rubyinside/the-new-absent-operator-in-ruby-s-regular-expressions-7c3ef6cd0b99" class="external">this article by Peter Cooper</a>.</p> Ruby master - Misc #16507 (Open): =~ vs include? or match?https://bugs.ruby-lang.org/issues/165072020-01-12T23:27:07ZMSP-Greg (Greg L)
<p>While working on getting the mswin build working on Actions, I thought adding mswin? and ci? methods to Minitest::Unit::Guard in tool/lib/minitest/unit.rb would be helpful.</p>
<p>Currently some tests are failing that are guarded/skipped based on ENV['APPVEYOR']. For ci?, I'd combine Travis, AppVeyor, & Actions.</p>
<p>There are quite a few instances where =~ is used for a boolean return. Would it be considered appropriate to replace those calls with include? or match?</p> Ruby master - Misc #16487 (Open): Potential for SIMD usage in ruby-corehttps://bugs.ruby-lang.org/issues/164872020-01-08T09:48:29Zbyroot (Jean Boussier)byroot@ruby-lang.org
<a name="Context"></a>
<h3 >Context<a href="#Context" class="wiki-anchor">¶</a></h3>
<p>There are several ruby core methods that could be optimized with the use of SIMD instructions.</p>
<p>I experimented a bit on <code>coderange_scan</code> <a href="https://github.com/Shopify/ruby/pull/2" class="external">https://github.com/Shopify/ruby/pull/2</a>, and Pavel Rosický experimented on <code>String#strip</code> <a href="https://github.com/ruby/ruby/pull/2815" class="external">https://github.com/ruby/ruby/pull/2815</a>.</p>
<a name="Problem"></a>
<h3 >Problem<a href="#Problem" class="wiki-anchor">¶</a></h3>
<p>The downside of SIMD instructions is that they are not universally available.<br>
So it means maintaining several versions of the same code, and switching them either statically or dynamically.</p>
<p>And since most Ruby users use precompiled binaries from repositories and such, it would need to be dynamic if we want most users to benefit from it.</p>
<p>So it's not exactly "free speed", as it means a complexified codebase.</p>
<a name="Question"></a>
<h3 >Question<a href="#Question" class="wiki-anchor">¶</a></h3>
<p>So the question is to know wether ruby-core is open to patches using SIMD instructions ? And if so under which conditions.</p>
<p>cc <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/10">@shyouhei (Shyouhei Urabe)</a></p> Ruby master - Misc #16436 (Open): hash missing #last method, make it not so consistent (it has #f...https://bugs.ruby-lang.org/issues/164362019-12-19T16:21:35Zzw963 (Wei Zheng)
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">(</span><span class="n">pry</span><span class="p">)</span><span class="ss">:main</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">></span> <span class="n">h</span> <span class="o">=</span> <span class="p">{</span><span class="n">x</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span><span class="mi">2</span><span class="p">,</span> <span class="n">z</span><span class="p">:</span><span class="mi">3</span><span class="p">}</span>
<span class="p">{</span>
<span class="ss">:x</span> <span class="o">=></span> <span class="mi">1</span><span class="p">,</span>
<span class="ss">:y</span> <span class="o">=></span> <span class="mi">2</span><span class="p">,</span>
<span class="ss">:z</span> <span class="o">=></span> <span class="mi">3</span>
<span class="p">}</span>
<span class="p">(</span><span class="n">pry</span><span class="p">)</span><span class="ss">:main</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">></span> <span class="n">h</span><span class="p">.</span><span class="nf">first</span>
<span class="p">[</span>
<span class="ss">:x</span><span class="p">,</span>
<span class="mi">1</span>
<span class="p">]</span>
<span class="p">(</span><span class="n">pry</span><span class="p">)</span><span class="ss">:main</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">></span> <span class="n">h</span><span class="p">.</span><span class="nf">first</span><span class="p">.</span><span class="nf">first</span>
<span class="ss">:x</span>
<span class="p">(</span><span class="n">pry</span><span class="p">)</span><span class="ss">:main</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">></span> <span class="n">h</span><span class="p">.</span><span class="nf">first</span><span class="p">.</span><span class="nf">last</span>
<span class="mi">1</span>
</code></pre>
<p>last method not exist.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">(</span><span class="n">pry</span><span class="p">)</span><span class="ss">:main</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">></span> <span class="n">h</span><span class="p">.</span><span class="nf">last</span>
<span class="no">Exception</span><span class="p">:</span> <span class="no">NoMethodError</span><span class="p">:</span> <span class="n">undefined</span> <span class="nb">method</span> <span class="sb">`last' for {:x=>1, :y=>2, :z=>3}:Hash
</span></code></pre>
<p>We have to use #to_a to make last working.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">(</span><span class="n">pry</span><span class="p">)</span><span class="ss">:main</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">></span> <span class="n">h</span><span class="p">.</span><span class="nf">to_a</span><span class="p">.</span><span class="nf">last</span>
<span class="p">[</span>
<span class="ss">:z</span><span class="p">,</span>
<span class="mi">3</span>
<span class="p">]</span>
<span class="p">(</span><span class="n">pry</span><span class="p">)</span><span class="ss">:main</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">></span> <span class="n">h</span><span class="p">.</span><span class="nf">to_a</span><span class="p">.</span><span class="nf">last</span><span class="p">.</span><span class="nf">first</span>
<span class="ss">:z</span>
<span class="p">(</span><span class="n">pry</span><span class="p">)</span><span class="ss">:main</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">></span> <span class="n">h</span><span class="p">.</span><span class="nf">to_a</span><span class="p">.</span><span class="nf">last</span><span class="p">.</span><span class="nf">last</span>
<span class="mi">3</span>
</code></pre> Ruby master - Misc #16408 (Open): Ruby docs list incorrect method signatures for PTY::getpty/PTY:...https://bugs.ruby-lang.org/issues/164082019-12-08T18:30:18Zyarmiganosca (Chris Hoffman)
<p>Ruby documentation says the method signature for <code>PTY::getpty</code>/<code>PTY::spawn</code> is</p>
<pre><code> * PTY.spawn(command_line) { |r, w, pid| ... }
* PTY.spawn(command_line) => [r, w, pid]
* PTY.spawn(command, arguments, ...) { |r, w, pid| ... }
* PTY.spawn(command, arguments, ...) => [r, w, pid]
</code></pre>
<p>However, running the following command with any Ruby since at least 2.1.9 (and based on git history, I believe since 2.0.0) will demonstrate that these method signatures are incorrect:</p>
<pre><code>ruby -rpty -e 'r, w, pid = PTY.spawn({"GREETING" => "hello"}, "echo $GREETING world"); puts r.gets(11); r.close; w.close'
</code></pre>
<p>(it will output <code>hello world</code>)</p>
<p>Further testing confirms that, aside from the block, <code>PTY::spawn</code> has the same method signature as <code>Kernel#exec</code>, <code>Kernel#system</code>, <code>Kernel#spawn</code>, and <code>Process::spawn</code>. This makes sense given that their C implementations all call the C method <code>rb_execarg_new</code> to handle the complex argument possibilities they all have to deal with.</p>
<p>I have a branch with tests that verify this: <a href="https://github.com/yarmiganosca/ruby/tree/fix-PTY-getpty-and-spawn-docs-and-tests" class="external">https://github.com/yarmiganosca/ruby/tree/fix-PTY-getpty-and-spawn-docs-and-tests</a></p>
<p>Travis isn't running CI on this branch, but I'm assuming that's account related and not an issue with my code, especially since the UI just informs me that I'm not allowed to.</p>
<p>I'm happy to also change the docs for <code>PTY::spawn</code> in this branch, but I wasn't sure which docs to emulate. The docs for this "family" of methods are inconsistent in how they explain the complicated options available to users:</p>
<ul>
<li>
<code>Kernel#spawn</code> explains in full the argument possibilities.</li>
<li>
<code>Kernel#exec</code> and <code>Kernel#system</code> both link to the docs for <code>Kernel#spawn</code>.</li>
<li>
<code>Process::spawn</code> explains in full (I think it might be a copy-paste job from the <code>Kernel#spawn</code> docs).</li>
<li>The docs for <code>IO::popen</code> (another method that uses the "execargs signature" with some modifications) list, but don't explain all the argument possibilities. They also don't do all that great a job at explaining where the other arguments from <code>IO::popen</code>'s signature fit alongside the "execargs signature".</li>
</ul>
<p>So it seems that there isn't consensus on the best way to explain this complex method signature (and modifications of it) to readers of the docs. Like I said, I'm happy to fix the <code>PTY::spawn</code> docs in this branch, but I was hoping for some guidance on which of the above documentation approaches to emulate.</p> Ruby master - Misc #16396 (Open): What is the reason for this behaviour of Find.find?https://bugs.ruby-lang.org/issues/163962019-12-03T13:03:26Zstiuna (Juan Gregorio)cart4for1@mail.com
<p>When I have a script at <code>D:\Downloads\Ruby 2.5.3\rbL\comp\codeShort.rb</code> with few other files in the same folder, the following searches only the folder where the <code>.rb</code> script is located:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Find</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="s1">'D:'</span><span class="p">)</span>
</code></pre>
<p>When I have a script at <code>D:\Downloads\Ruby 2.5.3\rbL\codeShort.rb</code> with many other files in the same folder, the same code as above searches the entire disk D.</p>
<p>To search the entire disk D in the first case, I did this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Find</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="s1">'D:/'</span><span class="p">)</span>
</code></pre>
<p>But I don't understand why the two cases behave differently with the same instruction just because they script are in different directories.</p> Ruby master - Misc #16346 (Open): Confusing macro name: RUBY_MARK_NO_PIN_UNLESS_NULLhttps://bugs.ruby-lang.org/issues/163462019-11-13T07:39:44Zy_kojima (Yohei Kojima)
<p>function <code>rb_gc_mark_no_pin</code> is renamed to <code>rb_gc_mark_movable</code> in the commit <code>aac4d9d6c7e6b6b0742f3941b574f6006ccb5672</code>.<br>
But macro <code>RUBY_MARK_NO_PIN_UNLESS_NULL</code> is not renamed then.</p>
<p>Now, <code>RUBY_MARK_NO_PIN_UNLESS_NULL</code> calls <code>rb_gc_mark_movable</code>; this is a bit confusing.<br>
So I suggest renaming <code>RUBY_MARK_NO_PIN_UNLESS_NULL</code> to <code>RUBY_MARK_MOVABLE_UNLESS_NULL</code> like this patch.</p> Ruby master - Misc #16267 (Open): MinGW CI - add to Actions ?https://bugs.ruby-lang.org/issues/162672019-10-21T01:10:18ZMSP-Greg (Greg L)
<p>Actions has three embedded MSYS2 installs, as they currently install the three Windows Rubies with 'DevKits'. So, MinGW could be built/tested on Actions.</p>
<p>I have a GH action at <a href="https://github.com/MSP-Greg/msys2-action" class="external">https://github.com/MSP-Greg/msys2-action</a> that's used in Puma's CI, it allows updating the 'toolchain' and additional packages (typically things like ragel, openssl, etc).</p>
<p>JFYI...</p> Ruby master - Misc #16235 (Open): ENV.assoc spec test does not test invalid namehttps://bugs.ruby-lang.org/issues/162352019-10-03T21:05:12Zburdettelamar@yahoo.com (Burdette Lamar)burdettelamar@example.com
<p>The most important thing here is an added test for an invalid name argument to ENV.assoc, which should raise TypeError.</p>
<p>I've also added to spec_helper.rb:</p>
<ul>
<li>Methods :reserve_names and :release_names, to reserve and release names used in the test.</li>
<li>Method :mock_to_str, to return a mock object that responds to :to_str.</li>
</ul>
<p>The updated assoc_spec.rb uses all of these, as will many other spec tests for ENV, as I get to them.</p>
<p>It's known that some of the ENV spec tests do not test a method's return value, and that some do not test error conditions (as above), so more to come. All in good time.</p> Ruby master - Misc #16160 (Open): Lazy init thread local storagehttps://bugs.ruby-lang.org/issues/161602019-09-09T21:36:28Zmethodmissing (Lourens Naudé)lourens@bearmetal.eu
<p>References PR <a href="https://github.com/ruby/ruby/pull/2295" class="external">https://github.com/ruby/ruby/pull/2295</a></p>
<a name="Why"></a>
<h3 >Why?<a href="#Why" class="wiki-anchor">¶</a></h3>
<p>The <code>local_storage</code> member of execution context is lazy initialized and drives the <code>Thread#[]</code> and <code>Thread#[]=</code> APIs, which are Fiber local and not Thread local storage. I think the same lazy init pattern should be applied to the APIs below as well - reduces one <code>Hash</code> alloc per thread created that does not use thread locals.</p>
<a name="Lazy-allocates-thread-local-storage-for-the-following-APIs"></a>
<h3 >Lazy allocates thread local storage for the following APIs<a href="#Lazy-allocates-thread-local-storage-for-the-following-APIs" class="wiki-anchor">¶</a></h3>
<ul>
<li>
<code>Thread#thread_variable_get</code> - early returns <code>nil</code> on locals Hash not initialised</li>
<li>
<code>Thread#thread_variable_set</code> - forces allocation of the locals Hash if not initilalised</li>
<li>
<code>Thread#thread_variables</code> - early returns the empty array AND saves on Hash iteration if locals Hash not initialised</li>
<li>
<code>Thread#thread_variable?</code> - early returns <code>false</code> on locals Hash not initialised</li>
</ul>
<a name="Other-notes"></a>
<h3 >Other notes<a href="#Other-notes" class="wiki-anchor">¶</a></h3>
<ul>
<li>Moved initial implementation from <code>internal.h</code> to <code>thread.c</code> local to call sites.</li>
<li>Preferred <code>defs/id.def</code> for the <code>locals</code> ID (seeing this pattern used more often, but not sure if that is preferred to inline <code>rb_intern</code> yet. Either way there's quite a few different conventions around IDs in the codebase at the moment and happy to help converging to a standard instead.</li>
<li>Maybe a flag is overkill and <code>NIL_P</code> on <code>locals</code> ivar could also work ...</li>
</ul>
<p>Thoughts?</p> Ruby master - Misc #16157 (Open): What is the correct and *portable* way to do generic delegation?https://bugs.ruby-lang.org/issues/161572019-09-09T14:10:42ZDan0042 (Daniel DeLorme)
<p>With the keyword argument changes in 2.7 we must now specify keyword arguments explicitly when doing generic delegation. But this change is not compatible with 2.6, where it adds an empty hash to the argument list of methods that do not need/accept keyword arguments.</p>
<p>To illustrate the problem:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">ProxyWithoutKW</span> <span class="o"><</span> <span class="no">BasicObject</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
<span class="vi">@target</span> <span class="o">=</span> <span class="n">target</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="o">*</span><span class="n">a</span><span class="p">,</span> <span class="o">&</span><span class="n">b</span><span class="p">)</span>
<span class="vi">@target</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="o">*</span><span class="n">a</span><span class="p">,</span> <span class="o">&</span><span class="n">b</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">ProxyWithKW</span> <span class="o"><</span> <span class="no">BasicObject</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
<span class="vi">@target</span> <span class="o">=</span> <span class="n">target</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="o">*</span><span class="n">a</span><span class="p">,</span> <span class="o">**</span><span class="n">o</span><span class="p">,</span> <span class="o">&</span><span class="n">b</span><span class="p">)</span>
<span class="vi">@target</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="o">*</span><span class="n">a</span><span class="p">,</span> <span class="o">**</span><span class="n">o</span><span class="p">,</span> <span class="o">&</span><span class="n">b</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Test</span>
<span class="k">def</span> <span class="nf">args</span><span class="p">(</span><span class="o">*</span><span class="n">a</span><span class="p">)</span> <span class="n">a</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">arg</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="n">a</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">opts</span><span class="p">(</span><span class="o">**</span><span class="n">o</span><span class="p">)</span> <span class="n">o</span> <span class="k">end</span>
<span class="k">end</span>
<span class="c1"># 2.6 2.7 3.0</span>
<span class="no">ProxyWithoutKW</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">Test</span><span class="p">.</span><span class="nf">new</span><span class="p">).</span><span class="nf">args</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span> <span class="c1"># [42] [42] [42] ok</span>
<span class="no">ProxyWithoutKW</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">Test</span><span class="p">.</span><span class="nf">new</span><span class="p">).</span><span class="nf">arg</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span> <span class="c1"># 42 42 42 ok</span>
<span class="no">ProxyWithoutKW</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">Test</span><span class="p">.</span><span class="nf">new</span><span class="p">).</span><span class="nf">opts</span><span class="p">(</span><span class="ss">k: </span><span class="mi">42</span><span class="p">)</span> <span class="c1"># {:k=>42} {:k=>42} +warn [{:k=>42}] incompatible with >= 2.7</span>
<span class="no">ProxyWithKW</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">Test</span><span class="p">.</span><span class="nf">new</span><span class="p">).</span><span class="nf">args</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span> <span class="c1"># [42, {}] [42] [42] incompatible with <= 2.6</span>
<span class="no">ProxyWithKW</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">Test</span><span class="p">.</span><span class="nf">new</span><span class="p">).</span><span class="nf">arg</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span> <span class="c1"># error 42 42 incompatible with <= 2.6</span>
<span class="no">ProxyWithKW</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">Test</span><span class="p">.</span><span class="nf">new</span><span class="p">).</span><span class="nf">opts</span><span class="p">(</span><span class="ss">k: </span><span class="mi">42</span><span class="p">)</span> <span class="c1"># {:k=>42} {:k=>42} +warn {:k=>42} must ignore warning? cannot use pass_positional_hash in 2.6</span>
</code></pre>
<p>I don't know how to solve this, so I'm asking for the <strong>official</strong> correct way to write portable delegation code. And by <strong>portable</strong> I mean code that can be used in gems that target ruby 2.6 and above.</p> Ruby master - Misc #16130 (Open): [Discussion / Ideas] Finding a good name for the concept of/beh...https://bugs.ruby-lang.org/issues/161302019-08-27T11:59:08Zshevegen (Robert A. Heiler)shevegen@gmail.com
<p>In recent presentions this year, and perhaps prior to that as well if I<br>
remember correctly, matz mentioned that the core team (and matz) may be<br>
looking for a good name to the concept of/behind guilds.</p>
<p>The thread here, this issue, is PRIMARILY confined with this, the name -<br>
if you have any good suggestion for names in this context, or discussions<br>
that may relate to this secondarily, please feel free to chime in and<br>
comment. This is primarily meant to give some ideas, possibly.</p>
<p>Since koichi is also heavily involved here (matz pointed out that koichi<br>
likes the name guilds, and came up with the idea/proposal/implementation),<br>
I think this should be considered too. And of course how ruby users may<br>
want to use/view the concept behind guilds, and actually use them in<br>
their own code - the best idea is not great if nobody is using the<br>
concept. Like with refinements ... great idea but I found the API<br>
somewhat strange. :D (May also be because subclassing is so easy with<br>
"Foo < Bar"; ideally we could have something like this with refinements<br>
too, but this is for another proposal or discussion - this here is<br>
about the name for the concept behind guilds.)</p>
<p>Anyway.</p>
<p>I'll give my opinion too, on the names, but I will decouple this from<br>
the initial suggestion here, and reply to my own issue.</p>
<p>Note that this here really is primarily concerned with finding a good<br>
NAME, which is not trivial, since names may have different meanings<br>
in different contexts.</p>
<p>Furthermore, some links for those who may be curious - some of which<br>
are old, and I really just randomly linked these in:</p>
<p><a href="http://www.atdot.net/~ko1/activities/2016_rubykaigi.pdf" class="external">http://www.atdot.net/~ko1/activities/2016_rubykaigi.pdf</a><br>
<a href="https://mensfeld.pl/2016/11/getting-ready-for-new-concurrency-in-ruby-3-with-guilds/" class="external">https://mensfeld.pl/2016/11/getting-ready-for-new-concurrency-in-ruby-3-with-guilds/</a><br>
<a href="https://olivierlacan.com/posts/concurrency-in-ruby-3-with-guilds/" class="external">https://olivierlacan.com/posts/concurrency-in-ruby-3-with-guilds/</a></p> Ruby master - Misc #16114 (Open): Naming of "beginless range"https://bugs.ruby-lang.org/issues/161142019-08-21T23:34:44Zpwim (Paul McMahon)paul@doorkeeper.jp
<p><a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Startless range (Closed)" href="https://bugs.ruby-lang.org/issues/14799">#14799</a> introduces a "beginless range" to complement the already existing "endless range". However, "beginless" isn't an existing word in English. Since the term for something without a beginning is "beginingless", I'd propose renaming "beginless range" to "beginningless range".</p> Ruby master - Misc #15744 (Open): Improvement needed to documentation of 'Literals'https://bugs.ruby-lang.org/issues/157442019-04-02T17:34:46ZCaryInVictoria (Cary Swoveland)cary@swoveland.com
<p>Documentation of "Literals" for v2.6.0 is given here: <a href="https://docs.ruby-lang.org/en/2.6.0/syntax/literals_rdoc.html" class="external">https://docs.ruby-lang.org/en/2.6.0/syntax/literals_rdoc.html</a>. (I don't think it has been changed for some time.) It gives examples of literals but does not provide a definition. It is comparable to defining an array by giving a few examples. I believe a definition is needed.</p>
<p>I would like to suggest a definition, but I confess I don't know what a Ruby literal is. A definition is attempted at this Wiki for computer programming generally: <a href="https://en.wikipedia.org/wiki/Literal_(computer_programming)" class="external">https://en.wikipedia.org/wiki/Literal_(computer_programming)</a>.</p>
<p>I suspect a Ruby literal is an object whose value is in some sense "known" at compile-time. For example, I would think <code>1</code>, <code>1.0</code> and <code>{ a: [1, 'cat', ['dog', ['pig', ..10]]] }</code> are literals but <code>{ v=>1, 2=>3 }</code> in <code>h = { v=>1, 2=>3 }</code>, <code>v</code> being a variable, is not. Or is it? If the previous line of code had been <code>v=3</code>, Ruby could, at compile-time, infer that the line could be replaced with <code>h = {3=>1, 2=>3}</code>, in which case it would be "known". This example is meant to illustrate why I earlier said "in some sense".</p> Ruby master - Misc #15654 (Open): Documentation for Complex is wrong or misleadinghttps://bugs.ruby-lang.org/issues/156542019-03-11T08:43:36Zsawa (Tsuyoshi Sawada)
<p>The documentation for <code>Complex</code> <a href="https://ruby-doc.org/core-2.6/Complex.html" class="external">https://ruby-doc.org/core-2.6/Complex.html</a> says or implies that a complex can be created by literal like <code>2+1i</code>, but that is actually calling the method <code>+</code> on receiver <code>2</code> with argument <code>1i</code>. The description should be changed to make it clear that <code>2+ 1i</code> is not a literal but is applying a method.</p> Ruby master - Misc #15568 (Open): TracePoint(:raise)#parameters raises RuntimeErrorhttps://bugs.ruby-lang.org/issues/155682019-01-26T21:10:29Zbaweaver (Brandon Weaver)keystonelemur@gmail.com
<p>Currently trying to get the <code>trace.parameters</code> of a method in a <code>raise</code> event will lead to a RuntimeError. I would contend that it should not, and that it would be perfectly valid to ask for the parameters in the case of an exception.</p>
<p>The reason I do this is to see the arguments at the time of exception:</p>
<pre><code>def extract_args(trace)
trace.parameters.map(&:last).to_h do |name|
[name, trace.binding.eval(name.to_s)]
end
end
</code></pre>
<p>I've noticed that I can technically "cheat" and get these same values like this:</p>
<pre><code>def extract_args(trace)
trace.binding.eval('local_variables').to_h do |name|
[name, trace.binding.eval(name.to_s)]
end
end
</code></pre>
<p>Having the ability to get the parameters in a <code>raise</code> context would be very useful for debugging.</p>
<p>I'm tempted to also suggest <code>TracePoint#local_variables</code> as it would provide additional context in a more exposed way than <code>TracePoint#binding.eval('local_variables')</code></p> Ruby master - Misc #15514 (Open): Add documentation for implicit array decompositionhttps://bugs.ruby-lang.org/issues/155142019-01-07T10:26:51Zsos4nt (Stefan Schüßler)mail@stefanschuessler.de
<p>The documentation for <a href="http://ruby-doc.org/core/doc/syntax/assignment_rdoc.html#label-Array+Decomposition" class="external">Array Decomposition</a> says: <em>"[...] you can decompose an Array during assignment using parenthesis [sic]"</em> and gives an example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span>
<span class="nb">p</span> <span class="ss">a: </span><span class="n">a</span><span class="p">,</span> <span class="ss">b: </span><span class="n">b</span> <span class="c1"># prints {:a=>1, :b=>2}</span>
</code></pre>
<p>But – as we all know – it's also possible <em>without</em> parentheses, i.e.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span>
<span class="nb">p</span> <span class="ss">a: </span><span class="n">a</span> <span class="p">,</span> <span class="ss">b: </span><span class="n">b</span> <span class="c1">#=> {:a=>1, :b=>2}</span>
</code></pre>
<p>This also applies to block arguments when yielding multiple values vs. yielding a single array:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">foo</span>
<span class="k">yield</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="k">yield</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span>
<span class="k">end</span>
<span class="n">foo</span> <span class="p">{</span> <span class="o">|</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="o">|</span> <span class="nb">p</span> <span class="ss">a: </span><span class="n">a</span><span class="p">,</span> <span class="ss">b: </span><span class="n">b</span> <span class="p">}</span>
<span class="c1">#=> {:a=>1, :b=>2}</span>
<span class="n">bar</span> <span class="p">{</span> <span class="o">|</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="o">|</span> <span class="nb">p</span> <span class="ss">a: </span><span class="n">a</span><span class="p">,</span> <span class="ss">b: </span><span class="n">b</span> <span class="p">}</span>
<span class="c1">#=> {:a=>1, :b=>2}</span>
</code></pre>
<p>In both cases, parentheses are optional.</p>
<p>This implicit array decomposition could be quite surprising for newcomers. The documentation should cover it.</p> Ruby master - Misc #15510 (Open): Easter egg in Thread.handle_interrupthttps://bugs.ruby-lang.org/issues/155102019-01-05T20:42:12Zlarskanis (Lars Kanis)
<p>The docs of <code>Thread.handle_interrupt</code> are quite clear about the argument to be passed. It must be a hash of <code>ExceptionClass => :TimingSymbol</code> pairs. I never thought that anything other than a <code>Exception</code> derivation would be accepted.</p>
<p>But then I read the tests to this method and wondered: <a href="https://github.com/ruby/ruby/blob/trunk/test/ruby/test_thread.rb#L783" class="external">Some of the tests</a> set <code>Object</code> as <code>ExceptionClass</code>. Moreover the method is not covered by ruby-spec and JRuby <a href="https://github.com/jruby/jruby/blob/66d2905ae233a39e36fcbe3ade6382c2892ade8e/test/mri/excludes/TestThread.rb" class="external">excludes several failing tests</a>.</p>
<p>So I inspected the code and found some obscure behavior: There are actually <a href="https://github.com/ruby/ruby/blob/trunk/thread.c#L115-L116" class="external">two non-exceptions</a> which can be masked by <code>Thread.handle_interrupt(Integer => :TimingSymbol)</code>. It is main thread termination and <code>Thread#kill</code>. Now this <a href="https://github.com/ruby/ruby/blob/trunk/thread.c#L1891-L1894" class="external">blur sentence in the docs</a> makes some more sense:</p>
<blockquote>
<p>interrupt means asynchronous event and corresponding procedure by Thread#raise, Thread#kill, signal trap (not supported yet) and main thread termination (if main thread terminates, then all other thread will be killed).</p>
</blockquote>
<p>So they are implemented as integers internally. However IMHO <code>Thread.handle_interrupt(Integer => :TimingSymbol)</code> is ... ugly.</p>
<p>Some proposals are:</p>
<ol>
<li>Make non-exceptions an ruby implementation specific feature, adjusts current tests and optionally add tests which are tagged as implementation specific.</li>
<li>Document it officially, but choose some more meaningful class names instead of <code>Integer</code>
</li>
</ol> Ruby master - Misc #15431 (Open): Hashes and arrays should not require commas to seperate values ...https://bugs.ruby-lang.org/issues/154312018-12-18T04:14:25Znsuchy (Nathaniel Suchy)me@lunorian.is
<p>Ruby should not require commas for hash and array values if using new lines. I think the syntax would look cleaner without.</p>
<p><strong>Example</strong></p>
<pre><code>myHash = {
:key => “value”,
:anotherKey => “another value”
}
</code></pre>
<p><strong>Could be</strong></p>
<pre><code>myHash = {
:key => “value”
:anotherKey => “another value”
}
</code></pre>
<p><strong>And</strong></p>
<pre><code>myArray = [
1,
2,
3
]
</code></pre>
<p>Could be:</p>
<pre><code>myArray = [
1
2
3
]
</code></pre>
<p>The syntax looks a bit cleaner, with the new lines is there a need to require a comma? I look forward to hearing the community’s thoughts on this idea :)</p> Ruby master - Misc #15418 (Open): Date.parse('2018')https://bugs.ruby-lang.org/issues/154182018-12-15T18:43:56Zfoonlyboy (Eike Dierks)
<p>Date.parse('2018')<br>
ArgumentError: invalid date</p>
<p>I did expect that to return the same as:<br>
Date.parse('2018-1-1')<br>
=> Mon, 01 Jan 2018</p>
<p>working with dates and times is really weird and complicated,<br>
so it makes sense to be strict with parsing.</p>
<p>I watched this one:<br>
<a href="https://www.youtube.com/watch?v=-5wpm-gesOY" class="external">https://www.youtube.com/watch?v=-5wpm-gesOY</a><br>
He's really coming up with some some crazy test cases.</p>
<p>In ruby this is split between Time and DateTime,<br>
some in the core, some in in the standard lib.</p>
<hr>
<p>Im looking forward for the new version,<br>
let's freeze the strings!</p>
<p>~eike</p> Ruby master - Misc #15402 (Open): Shrinking excess retained memory of container types on promotio...https://bugs.ruby-lang.org/issues/154022018-12-11T20:43:38Zmethodmissing (Lourens Naudé)lourens@bearmetal.eu
<p>I've been toying with the idea of the viability of attempting to reclaim over provisioned memory from buffer capacity of container objects like <code>Array</code> and <code>String</code>, effectively reducing the footprint of retained memory of such objects.</p>
<p>GC at the moment covers these dominant paths:</p>
<ul>
<li>Collection of shallow memory: unreferenced object slot with values encoded on the object</li>
<li>Collection of retained memory: unreferenced object slot with off ruby object heap pointer to String buffer, Array buffer etc. (<code>heap.aux</code>)</li>
<li>Finalization hooks like reclaiming resources for <code>Tempfile</code> for example</li>
</ul>
<p>I explored in <a href="https://github.com/ruby/ruby/pull/2037" class="external">https://github.com/ruby/ruby/pull/2037</a> (more details and data points on the PR) a forth one:</p>
<ul>
<li>Shrinking over provisioned buffer capacity of <code>Array</code> (also applies to <code>String</code> and likely others) on promotion to uncollectible (<code>Also garbage collect excess retained space from types with a first class capacity and buffer on promotion to uncollectible</code>)</li>
</ul>
<p>Sharing here for feedback in case anyone has ideas for a more appropriate hook, or additional precondition for such a hook. Or if excess buffer capacity can even be considered first class garbage in a GC context.</p>
<p>I chose <code>Array</code> as a proof of concept because the type already have this optimization through <code>ary_shrink_capa</code> through <code>ary_make_shared</code> and the threshold for not encoding members on the object is quite low at 3 elements. Plausible that many framework / boot specific long lived arrays are larger than that and because the growth factor on expansion is <code>2x</code>, also likely a fair amount of over provisioned capacity.</p>
<p>Results of the changeset:</p>
<ul>
<li>Benchmark <code>so_binary_trees</code> - <code>26%</code> reduction in total memory usage</li>
<li>Also a very noticeable <code>24%</code> difference with <code>app_lc_fizzbuzz</code>
</li>
<li>General few bytes reduction for almost all core benchmarks</li>
<li>Mainline <code>redmine</code> after boot - <code>1.5%</code> or <code>45kb</code> reduction in <code>Array</code> retained memory size</li>
</ul>
<p>Implementation caveats:</p>
<ul>
<li>Promotion to uncollectible may be a bad heuristic for shrinking buffer capacity.</li>
<li>Needed to create a new <code>rb_ary_shrink_capa</code> function as <code>ary_shrink_capa</code> is private API and has several assertions (frozen and shared check) that hard fails during GC. That way shrinking responsibility and accounting remains the responsibility of <code>array.c</code> - the GC just calls it (same as with the <code>memsize</code> APIs)</li>
<li>I tried running it during GC which worked fine for benchmarks like <code>so_binary_trees</code> but failed under GC stress and larger heaps because of <code>TRY_WITH_GC</code> via <code>objspace_xrealloc</code>, which can invoke GC</li>
<li>A reasonable workaround for this was to use the postponed job API which is used by GC for object finalization, but that's one job per object space, not 1 per Array being shrinked, which may hit the 1000 item postponed job buffer for some heaps. It degrades gracefully though with fallback being the optimization simply not being applied to the excess objects in the set.</li>
<li>Have no idea about the future of the postponed job API and if this is an appropriate use case</li>
<li>
<code>RVALUE_PAGE_OLD_UNCOLLECTIBLE_SET</code> only special cases <code>Array</code> at the moment - it's easy to support other types</li>
</ul>
<p>Outliers to still evaluate:</p>
<ul>
<li>Fragmentation does not get significantly worse through <code>reallocs</code> for specific rare cases post GC (no data)</li>
<li>The effect of <code>objspace_malloc_increase</code> called by <code>objspace_xrealloc</code> on GC frequency (I think not much given the small reduction on retained usage, but have no data to prove yet)</li>
<li>How well the postponed job pattern scales to large heaps and how much of the job slots are consumed (no data)</li>
</ul>
<p>Thoughts on exploring more types or is the pattern tainted / broken to begin with?</p> Ruby master - Misc #15249 (Open): Documentation for attr_accessor and attr_reader should be corre...https://bugs.ruby-lang.org/issues/152492018-10-23T20:09:02ZCaryInVictoria (Cary Swoveland)cary@swoveland.com
<p>The documentation for <a href="http://ruby-doc.org/core-2.5.1/Module.html#method-i-attr_accessor" class="external">Module#attr_accessor</a> (v2.5.1) begins, "Defines a named attribute for this module, where the name is symbol.id2name, creating an instance variable (@name) and...". Similarly, the documentation for <a href="http://ruby-doc.org/core-2.5.1/Module.html#method-i-attr_reader" class="external">Module#attr_reader</a> states, "Creates instance variables and...". These statements do not appear to be correct:</p>
<pre><code>class C
attr_accessor :dog
attr_reader :cat
end
C.new.instance_variables #=> []
</code></pre> Ruby master - Misc #15224 (Open): [DOCs] Minor inconsistency in class Array #initialize_copy - ht...https://bugs.ruby-lang.org/issues/152242018-10-13T10:18:57Zshevegen (Robert A. Heiler)shevegen@gmail.com
<p>Today I looked at:</p>
<p><a href="https://ruby-doc.org/core-2.5.1/Array.html#method-i-initialize_copy" class="external">https://ruby-doc.org/core-2.5.1/Array.html#method-i-initialize_copy</a></p>
<p>The example to this method is this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span> <span class="o">=</span> <span class="p">[</span> <span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">,</span> <span class="s2">"d"</span><span class="p">,</span> <span class="s2">"e"</span> <span class="p">]</span>
<span class="n">a</span><span class="p">.</span><span class="nf">replace</span><span class="p">([</span> <span class="s2">"x"</span><span class="p">,</span> <span class="s2">"y"</span><span class="p">,</span> <span class="s2">"z"</span> <span class="p">])</span> <span class="c1">#=> ["x", "y", "z"]</span>
<span class="n">a</span> <span class="c1">#=> ["x", "y", "z"]</span>
</code></pre>
<p>What confused me was that I was looking at the method called <code>initialize_copy</code><br>
but the example showed <code>.replace()</code>.</p>
<p>I then looked at <code>#replace</code> there:</p>
<p><a href="https://ruby-doc.org/core-2.5.1/Array.html#method-i-replace" class="external">https://ruby-doc.org/core-2.5.1/Array.html#method-i-replace</a></p>
<p>And it was virtually identical to <code>initialize_copy</code>.</p>
<p>I assume the examples for <code>.replace()</code> are correct; and perhaps <code>initialize_copy</code><br>
is just an alias? I am not sure, but I would like to suggest to make the documentation,<br>
in particular the example, a bit more consistent.</p>
<p>When you click on "view source" to look at the C code, they show the very same<br>
content, so I believe that initialize_copy is merely an alias to replace; but I tried<br>
this and they are not fully equivalent:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">x</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">]</span> <span class="c1"># => [1, 2, 3]</span>
<span class="n">x</span><span class="p">.</span><span class="nf">initialize_copy</span> <span class="p">[</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">]</span>
</code></pre>
<pre><code>Traceback (most recent call last):
2: from /System/Index/bin/irb:11:in `<main>'
1: from (irb):2
NoMethodError (private method `initialize_copy' called for [1, 2, 3]:Array)
</code></pre>
<p>Yet:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">x</span><span class="p">.</span><span class="nf">replace</span> <span class="p">[</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">]</span> <span class="c1"># => [4, 5, 6]</span>
</code></pre>
<p>works. So I assume that <code>initialize_copy</code> is like <code>.replace()</code> but is a private<br>
method instead.</p>
<p>Perhaps it may help to add a sentence below the documentation of<br>
<code>replace()</code>, to explain what the use case for <code>initialize_copy</code> is. Or to perhaps<br>
mention that it is an alias.</p>
<p>At the least how it is right now is that people may read <code>initialize_copy</code>,<br>
but then see an example of <code>#replace</code>. (Perhaps an example for<br>
<code>initialize_copy</code> may help, but either way, I think the current docu-example<br>
is not ideal).</p> Ruby master - Misc #15202 (Open): Adding Coverity Scan to CI to see the result casuallyhttps://bugs.ruby-lang.org/issues/152022018-10-04T14:06:33Zjaruga (Jun Aruga)
<p>Recently I reported issues detected by code analysis tool mainly using Coverity Scan.</p>
<p>The 9 issues categorized as "important" was fixed by <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Fixing issues detected by an Analysis tool. (Closed)" href="https://bugs.ruby-lang.org/issues/15116">#15116</a>. (Thank you!)</p>
<blockquote>
<p><a href="https://bugs.ruby-lang.org/issues/15116" class="external">https://bugs.ruby-lang.org/issues/15116</a></p>
<p>However as a "not important" issues, around 1000 issues were detected by the tool for the ruby 2.5.1.<br>
I am considering how to deal with this or report those.<br>
I might open an another ticket for that.</p>
</blockquote>
<p>However there are around 1000 "not important" issues.</p>
<p>Right now I do not share the report file (840KByte) for that, because it makes people tired.<br>
If someone want to see it, I am happy to share it here as an attachment.</p>
<p>Instead of that, It looks good to me that someone could see the result of coverity scan casually anytime to fix those in long term.</p>
<p>What I want to propose is to add coverity scan test on rubyci or Travis CI.</p>
<p>I do not know how coverity scan is used on current Ruby project as a regular workflow.<br>
But I could see it is actually used from the setting [2] and some tickets. [3]</p>
<p>I found how to use Coverity Scan on Travis CI [4], and the used cases [5][6].</p>
<p>How do you think?</p>
<ul>
<li>[1] rubyci: <a href="https://www.rubyci.org/" class="external">https://www.rubyci.org/</a>
</li>
<li>[2] coverity scan ruby project: <a href="https://scan.coverity.com/projects/ruby" class="external">https://scan.coverity.com/projects/ruby</a>
</li>
<li>[3] coverity scan used tickets:
<ul>
<li><a href="https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/61862" class="external">https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/61862</a></li>
<li><a href="https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/55763" class="external">https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/55763</a></li>
<li><a href="https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/50734" class="external">https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/50734</a></li>
</ul>
</li>
<li>[4] How to use Coverity Scan on Travis CI: <a href="https://scan.coverity.com/travis_ci" class="external">https://scan.coverity.com/travis_ci</a>
</li>
<li>[5] The cases for coverity scan on Travis CI:
<ul>
<li><a href="https://github.com/nanoporetech/scrappie/blob/master/.travis.yml" class="external">https://github.com/nanoporetech/scrappie/blob/master/.travis.yml</a></li>
<li><a href="https://github.com/JanusGraph/janusgraph/blob/master/.travis.yml" class="external">https://github.com/JanusGraph/janusgraph/blob/master/.travis.yml</a></li>
</ul>
</li>
</ul> Ruby master - Misc #15136 (Open): Fix -Wparentheses warningshttps://bugs.ruby-lang.org/issues/151362018-09-18T14:43:35Zjaruga (Jun Aruga)
<p>Currently the <code>-Wno-parentheses</code> was set.<br>
I assumed if we could fix the warning, we could remove the <code>-Wno-parentheses</code>.</p>
<p>I fixed the warnings, because the warning is used as a default on Fedora Project build environment.<br>
I sent pull-request. <a href="https://github.com/ruby/ruby/pull/1958" class="external">https://github.com/ruby/ruby/pull/1958</a></p>
<p>I would show you the explanation of <code>-Wparentheses</code>.</p>
<pre><code>$ man gcc (or gcc --help --verbose)
...
-Wparentheses
Warn if parentheses are omitted in certain contexts, such as when there is an
assignment in a context where a truth value is expected, or when operators are
nested whose precedence people often get confused about.
Also warn if a comparison like "x<=y<=z" appears; this is equivalent to "(x<=y ?
1 : 0) <= z", which is a different interpretation from that of ordinary
mathematical notation.
Also warn for dangerous uses of the GNU extension to "?:" with omitted middle
operand. When the condition in the "?": operator is a boolean expression, the
omitted value is always 1. Often programmers expect it to be a value computed
inside the conditional expression instead.
For C++ this also warns for some cases of unnecessary parentheses in
declarations, which can indicate an attempt at a function call instead of a
declaration:
{
// Declares a local variable called mymutex.
std::unique_lock<std::mutex> (mymutex);
// User meant std::unique_lock<std::mutex> lock (mymutex);
}
This warning is enabled by -Wall.
...
</code></pre> Ruby master - Misc #14825 (Open): When redefining `attr_xx` methods the visibility becomes `public` https://bugs.ruby-lang.org/issues/148252018-06-05T05:57:56Zy-yagi (Yuji Yaginuma)
<p>Hi.</p>
<p>If redefine <code>attr_xx</code> methods, the original visibility is lost and all visibility is public.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># attr.rb</span>
<span class="k">module</span> <span class="nn">ClassMethods</span>
<span class="k">def</span> <span class="nf">attr_reader</span><span class="p">(</span><span class="o">*</span><span class="p">)</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">attr_writer</span><span class="p">(</span><span class="o">*</span><span class="p">)</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">attr_accessor</span><span class="p">(</span><span class="o">*</span><span class="p">)</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Foo</span>
<span class="kp">extend</span> <span class="no">ClassMethods</span>
<span class="k">class</span> <span class="o"><<</span> <span class="nb">self</span>
<span class="k">def</span> <span class="nf">method_visibility</span><span class="p">(</span><span class="nb">method</span><span class="p">)</span>
<span class="k">case</span>
<span class="k">when</span> <span class="nb">private_method_defined?</span><span class="p">(</span><span class="nb">method</span><span class="p">)</span>
<span class="ss">:private</span>
<span class="k">when</span> <span class="nb">protected_method_defined?</span><span class="p">(</span><span class="nb">method</span><span class="p">)</span>
<span class="ss">:protected</span>
<span class="k">else</span>
<span class="ss">:public</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">attr_reader</span> <span class="ss">:pub</span>
<span class="kp">protected</span>
<span class="nb">attr_reader</span> <span class="ss">:prot</span>
<span class="k">alias</span> <span class="n">protalias</span> <span class="n">prot</span>
<span class="kp">alias_method</span> <span class="ss">:protaliasmethod</span><span class="p">,</span> <span class="ss">:prot</span>
<span class="kp">private</span>
<span class="nb">attr_reader</span> <span class="ss">:priv</span>
<span class="k">alias</span> <span class="n">privalias</span> <span class="n">priv</span>
<span class="kp">alias_method</span> <span class="ss">:privaliasmethod</span><span class="p">,</span> <span class="ss">:priv</span>
<span class="k">end</span>
<span class="n">f</span> <span class="o">=</span> <span class="no">Foo</span><span class="p">.</span><span class="nf">new</span>
<span class="nb">puts</span> <span class="s2">"Public"</span>
<span class="n">f</span><span class="p">.</span><span class="nf">pub</span>
<span class="nb">puts</span>
<span class="nb">puts</span> <span class="s2">"Protected"</span>
<span class="nb">puts</span> <span class="s2">"prot: </span><span class="si">#{</span><span class="no">Foo</span><span class="p">.</span><span class="nf">method_visibility</span><span class="p">(</span><span class="ss">:prot</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span>
<span class="nb">puts</span> <span class="s2">"protalias: </span><span class="si">#{</span><span class="no">Foo</span><span class="p">.</span><span class="nf">method_visibility</span><span class="p">(</span><span class="ss">:protalias</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span>
<span class="nb">puts</span> <span class="s2">"protaliasmethod </span><span class="si">#{</span><span class="no">Foo</span><span class="p">.</span><span class="nf">method_visibility</span><span class="p">(</span><span class="ss">:protaliasmethod</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span>
<span class="nb">puts</span>
<span class="nb">puts</span> <span class="s2">"Private"</span>
<span class="nb">puts</span> <span class="s2">"priv: </span><span class="si">#{</span><span class="no">Foo</span><span class="p">.</span><span class="nf">method_visibility</span><span class="p">(</span><span class="ss">:priv</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span>
<span class="nb">puts</span> <span class="s2">"privalias: </span><span class="si">#{</span><span class="no">Foo</span><span class="p">.</span><span class="nf">method_visibility</span><span class="p">(</span><span class="ss">:privalias</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span>
<span class="nb">puts</span> <span class="s2">"privaliasmethod: </span><span class="si">#{</span><span class="no">Foo</span><span class="p">.</span><span class="nf">method_visibility</span><span class="p">(</span><span class="ss">:privaliasmethod</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span>
</code></pre>
<pre><code>$ ruby -v attr.rb
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
Public
Protected
prot: public
protalias: public
protaliasmethod public
Private
priv: public
privalias: public
privaliasmethod: public
</code></pre>
<p>Is this intentional?</p> Ruby master - Misc #14770 (Open): [META] DevelopersMeetinghttps://bugs.ruby-lang.org/issues/147702018-05-17T12:28:50Znaruse (Yui NARUSE)naruse@airemix.jp
<p>A meta ticket to organize DevelopersMeeting tickets.<br>
<a href="https://bugs.ruby-lang.org/projects/ruby/wiki#Developer-Meetings" class="external">https://bugs.ruby-lang.org/projects/ruby/wiki#Developer-Meetings</a></p> Ruby master - Misc #14768 (Open): Add documentation for || and &&https://bugs.ruby-lang.org/issues/147682018-05-17T08:41:39Zsos4nt (Stefan Schüßler)mail@stefanschuessler.de
<p>The Ruby documentation doesn't seem to cover <code>||</code> and <code>&&</code>.</p>
<p>The only references I could find are:</p>
<p><a href="http://ruby-doc.org/core-2.5.1/doc/keywords_rdoc.html" class="external">http://ruby-doc.org/core-2.5.1/doc/keywords_rdoc.html</a></p>
<blockquote>
<p><strong>and</strong> – Short-circuit Boolean and with lower precedence than <code>&&</code><br>
<strong>or</strong> – Short-circuit Boolean and with lower precedence than <code>||</code></p>
</blockquote>
<p><a href="http://ruby-doc.org/core-2.5.1/doc/syntax/assignment_rdoc.html" class="external">http://ruby-doc.org/core-2.5.1/doc/syntax/assignment_rdoc.html</a></p>
<blockquote>
<p>There are also <code>||=</code> and <code>&&=</code>. The former makes an assignment if ...</p>
</blockquote>
<p>But there's no documentation for the operators themselves.</p> Ruby master - Misc #14735 (Open): thread-safe operations in a hash could be documentedhttps://bugs.ruby-lang.org/issues/147352018-05-03T18:55:46Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<p>Hi, sometimes I find myself fetching data from the database through multiple queries concurrently. For example, suppose the application support multiple data-types which are independent from each other and we need to perform a set of operations per data-type. Usually I'd run one method for extracting the related data per data-type and would run them concurrently. Something like this:</p>
<pre><code>require 'thread'
result = {} # assume this is thread-safe in MRI for now
data_types.map do |data_type, processor|
Thread.start{ result[data_type] = processor.call }
end.each &:join
</code></pre>
<p>This code is quite simple and seems to always work with MRI. A more explicit equivalent code that should also work on other Ruby implementations without GIL would be probably written like:</p>
<pre><code>require 'thread'
result = {}
result_semaphore = Mutex.new
data_types.map do |data_type, processor|
Thread.start do
result_for_data_type = processor.call # expensive call
result_semaphore.synchronize{ result[data_type] = result_for_data_type }
end
end.each &:join
</code></pre>
<p>As you can see, it's much more code than the previous one. As I said initially, I use such pattern every now and then, so I'd love to be able to write the first code and being confident that it would always work as expected in MRI.</p>
<p>I've tried the following in order to see if I could cause an thread-unsafe case with MRI but it always return "[ 100000, 100000, nil ]":</p>
<pre><code>require 'thread'
h = {}
(1..100000).map do |i|
Thread.start{ h[i] = i }
end.each &:join
p h.keys.uniq.size, h.values.uniq.size, h.find{|k, v| k != v }
</code></pre>
<p>Is it just by chance? Or may I assume that will always be the case. Maybe it would be interesting to document somewhere what could be assumed to be true regarding thread-safeness for many methods. For example, there could be some link in the Hash documentation such as: "If you'd like to understand how each method behave in a multi-thread environment read this document" and point to another page explaining how it works.</p>
<p>By the way, the 'concurrent' gem seems to assume Hash is thread-safe in MRI as you can see here:</p>
<p><a href="https://github.com/ruby-concurrency/concurrent-ruby/blob/master/lib/concurrent/hash.rb#L5-L16" class="external">https://github.com/ruby-concurrency/concurrent-ruby/blob/master/lib/concurrent/hash.rb#L5-L16</a></p>
<pre><code>module Concurrent
if Concurrent.on_cruby?
class Hash < ::Hash;
end
#...
end
end
</code></pre>
<p>Is this officially documented somewhere?</p> Ruby master - Misc #14673 (Open): Documentation for `Array#drop` / `drop_while` unclear in regard...https://bugs.ruby-lang.org/issues/146732018-04-10T09:51:49Zsos4nt (Stefan Schüßler)mail@stefanschuessler.de
<p>The documentation for <a href="http://ruby-doc.org/core-2.5.0/Array.html#method-i-drop" class="external"><code>Array#drop</code></a> says:</p>
<blockquote>
<p>Drops first <code>n</code> elements from <code>ary</code> and returns the rest of the elements in an array.</p>
</blockquote>
<p>It's unclear if the receiver is being changed or not (it is not). The documentation should be more explicit in that regard.</p>
<p>Maybe something like <em>"Returns a new array containing all except the first <code>n</code> elements from <code>ary</code>"</em>.</p>
<p>This also applies to <code>Array#drop_while</code>.</p> Ruby master - Misc #14190 (Open): What are the semantics of $SAFE?https://bugs.ruby-lang.org/issues/141902017-12-15T16:29:10ZEregon (Benoit Daloze)
<p>$SAFE is documented in many places as thread-local, but it seems more than that.<br>
For example:</p>
<pre><code># a.rb
$SAFE=1
p $SAFE
require "#{Dir.pwd.untaint}/b.rb"
# b.rb
p [:in_b, $SAFE]
</code></pre>
<p>gives:</p>
<pre><code>$ ruby -r./a -e 'p $SAFE'
1
[:in_b, 0]
0
</code></pre>
<p>So in b and in -e, $SAFE is 0.<br>
Is it file-based somehow?</p>
<p>I was trying to understand what<br>
<a href="https://github.com/ruby/ruby/blob/7c4306e6e9c3c4a255f4ad20134c1832dbe45ba2/test/rubygems/test_gem.rb#L9-L13" class="external">https://github.com/ruby/ruby/blob/7c4306e6e9c3c4a255f4ad20134c1832dbe45ba2/test/rubygems/test_gem.rb#L9-L13</a><br>
is supposed to do.<br>
Does it make sense? What does it do?<br>
It seems the test_* methods in that file actually read $SAFE as 0, not 1.</p> Ruby master - Misc #14149 (Open): Ruby Birthday Thread - 25th years anniversaryhttps://bugs.ruby-lang.org/issues/141492017-12-02T01:07:30Zshevegen (Robert A. Heiler)shevegen@gmail.com
<p>Hello Ruby-people in general,</p>
<p>Matz recently gave a keynote presentation and he mentioned that ruby's birthday will be<br>
in 2018 (25 years; I think matz mentioned that he counts when the name was chosen but<br>
ruby itself may have already been existing before that in one way or another perhaps).</p>
<p>I suggest that in this thread here, people can give feedback, give ideas, chat about<br>
things ... the party will be in Japan though, so not everyone can participate. :D</p>
<p>However had, as this here can be a thread where people can "virtually" add/contribute<br>
anything, I thought that it may be a good idea to start a thread here.</p>
<p>In order to not have this thread be active for too long, I suggest that it should<br>
be closed some time in 2018, after the ruby birthday party. :D</p>
<p>(I think the official birthday will be around February 2018, so I suggest that<br>
this thread should perhaps "fade out" some time in June or July 2018 or so?<br>
Something like that perhaps, but do feel free to ignore this too when appropriate,<br>
it is just a suggestion.)</p>
<p>I'll start with some feedback next from my point of view, but this thread should be<br>
general, not "just" my opinion. People really should give feedback, matz said so<br>
specifically in the keynote presentation.</p> Ruby master - Misc #14037 (Open): Writing doxygen document comments to static functionshttps://bugs.ruby-lang.org/issues/140372017-10-21T07:46:19Zsonots (Naotoshi Seo)sonots@gmail.com
<p>I often feel that C API documents are lacked in C source codes, especially for <code>static</code> functions.</p>
<p>With <a href="https://bugs.ruby-lang.org/issues/904" class="external">https://bugs.ruby-lang.org/issues/904</a>, <code>make install-capi</code> target was introduced to generate c api documents using Doxygen.<br>
However, I feel that it is not utilized among C Ruby developers.</p>
<p>I propose to turn <code>EXTRACT_STATIC = YES</code> flag of Doxygen to YES, and write document comments for static functions as much as possible.</p> Ruby master - Misc #13968 (Open): [Ruby 3.x perhaps] - A (minimal?) static variant of rubyhttps://bugs.ruby-lang.org/issues/139682017-10-03T20:42:16Zshevegen (Robert A. Heiler)shevegen@gmail.com
<p>Hello ruby core team and everyone else,</p>
<p>I think this has been brought up before, in one way or the other, but<br>
just in case it was not, or not in this context, I would like to <strong>propose<br>
that ruby can be compiled statically</strong>.</p>
<p>Matz explained how this can be done for mruby:</p>
<p><a href="https://github.com/mruby/mruby/issues/3707" class="external">https://github.com/mruby/mruby/issues/3707</a></p>
<p>This is not so difficult; allow me to copy/paste the major<br>
steps for mruby (I modified it a bit):</p>
<p>Option A:</p>
<pre><code>(1) compile your.rb files into a C file via mrbc. Example: "mrbc -Binit_yourlib -o mrblib.c *.rb"
(2) your code/application has to call "init_yourlib(mrb)" after "mrb_open()"
(3) compile your code/application with the generated C file
(4) link via "libmruby.a"
(5) static link options may have to be specified to the linker
</code></pre>
<p>Option B</p>
<pre><code>(1) Create a binary "mrbgem". See mrbgems/mruby-bin-mirb for example.
</code></pre>
<p>And nobu added better support for statically linked extensions some years<br>
ago:</p>
<p><a href="https://bugs.ruby-lang.org/issues/9018" class="external">https://bugs.ruby-lang.org/issues/9018</a></p>
<p>Since time is a limited resource by the ruby core team, I understand that<br>
you have to prioritize on issues that are more important, or needed more;<br>
and a statically compiled ruby may not be of highest priority. Additionally,<br>
you may want to know the use case of people, as to why they may want to<br>
have a statically compiled variant of ruby.</p>
<p>I have a (small) use case which I think has not been explained before.</p>
<p>I often break stuff on my linux system when I compile programs. I use many<br>
ruby helper scripts to compile programs, so I need ruby. :)</p>
<p>When I have a ruby available then I can often batch-compile, batch-install<br>
and so on. This works very well so far for most programs out there.</p>
<p>Not always is there a host system available with ruby though; sometimes<br>
I may be in a confined environment, such as workspaces at university<br>
and a central server cluster to which I have no access (or rather,<br>
permission to change files/directory). So I tend to compile into the<br>
user directory there (home directory).</p>
<p>Anyway. Since I tend to break stuff, but sometimes other stuff is also<br>
broken on such environments (looking at centos ...), I made it a habit<br>
to compile some of the core utilities in a static manner into my home<br>
directory; "make" for example or "sed". Both work very well. Others<br>
are a bit misbehaving or stubborn, such as awk - I haven't managed<br>
a statically compiled variant of awk yet.</p>
<p>Of course I also use "busybox," a statically compiled busybox that is.</p>
<p>This allows me to recover from many problems or errors if things go<br>
awry (I can also use a live-DVD for recovery, at the least at home;<br>
or also download some binaries that I know will work on the target<br>
platform, so I have more ways to recover).</p>
<p>Now the thing is - most of what I do with busybox, has to do with<br>
file manipulation of some sort; setting new symlinks, removing,<br>
moving, creating files or directories.</p>
<p>Here I thought - I could use ruby rather than busybox. :)</p>
<p>But I'd want or need a statically compiled ruby, so that it does not<br>
break depending on other programs there on the system.</p>
<p>I hope I could explain my use case. And I agree, only very few<br>
people may ever want to have this perhaps.</p>
<p>I looked at my self-compiled MRI ruby, via "ldd", and these are the<br>
libraries that ruby depends on:</p>
<pre><code> linux-vdso.so.1
libpthread.so.0 => /lib64/libpthread.so.0
libgmp.so.10 => /usr/lib/libgmp.so.10
libdl.so.2 => /lib64/libdl.so.2
libcrypt.so.1 => /lib64/libcrypt.so.1
libm.so.6 => /lib64/libm.so.6
libc.so.6 => /lib64/libc.so.6
/lib64/ld-linux-x86-64.so.2
</code></pre>
<p>I guess this is not minimal; I could probably re-compile ruby<br>
from a sandbox, to reduce the amount of .so objects that are<br>
needed, but the above is only an example anyway.</p>
<p>I assume that making available a ruby that can be statically compiled,<br>
is not trivial. It is probably easier for mruby, but mruby is, as far<br>
as I understand it, more aimed towards knowledgable C/C++ hackers. I<br>
am a bit too scared to try mruby when I do not really know C.</p>
<p>I should also state that I do not need a "full" ruby by the way. I can<br>
live without the extension stuff, such as "readline" or "openssl" probably<br>
(though I'd love to have open-uri since that may help in recovery; ruby's<br>
open() functionality for remote data/websites is great).</p>
<p>I guess the core functionality I would need is, mostly, file manipulation.</p>
<p>So perhaps my request could be titled:</p>
<p>"A minimal variant of ruby - that is statically linked."</p>
<p>Now this may fit to mruby perhaps but I am a bit scared of mruby also<br>
because I do not know mruby very well; I mostly work with MRI ruby. (I<br>
did manage to compile mruby without problem and I could run ruby code<br>
too but I am not sure how much is available on mruby by default "out<br>
of the box". If I remember correctly, not every MRI ruby .rb file<br>
will work "out of the box")</p>
<p>I also thought of filing an issue request at github-mruby but then I<br>
thought that perhaps it may also fit into MRI ruby one day, which is<br>
why I prepended with the ruby 3.x label. (I suppose that it may not<br>
fit towards 2.x anymore since 2.x will probably focus on stability,<br>
bug fixing and so forth.)</p>
<p>I hope I could explain my use case. I am not sure if it is a good<br>
use case; I can probably just keep on using busybox ... but I would<br>
prefer to actually work within a "ruby environment" in general,<br>
simply because ruby is a LOT nicer to work with, in particular for<br>
batch-automated tasks (I always prefer to use ruby rather than shell<br>
scripts, for example).</p>
<p>If possible it would be nice if this issue could remain open for a<br>
bit longer, if only to see if there is anyone else who may want to<br>
have some statically compiled variant of ruby.</p>
<p>I see this sometimes in other issue requests, or similar suggestions,<br>
so perhaps if there may be a seizable amount of people who may want<br>
it, it could be put on a "long-term goal". Perhaps even past 3.x.</p>
<p>Last but not least I would like to repeat that I do not need a full<br>
featured ruby per se, a minimal may suffice - but that minimal ruby<br>
should ideally be easy to use+install. It's a bit like a mix<br>
between "MRI ruby" and "mruby" what I want, I think. :D</p>
<p>That way, I could both have a MRI ruby that uses .so, but also e. g<br>
a binary called "static-ruby" or "ruby-static" or something like<br>
that, that can be used a bit like a "recovery ruby".</p>
<p>I wrote a lot so now it's time to close without much further ado -<br>
thank you for reading!</p> Ruby master - Misc #13804 (Open): Protected methods cannot be overriddenhttps://bugs.ruby-lang.org/issues/138042017-08-10T21:41:24Zdavidarnold (David Arnold)
<p>In Ruby, the main reason you would use protected instead of private is because you want different instances of the same class lineage to be able to access the method.</p>
<p>However, the rules around protected (callable only where self of the context is the same as the [...] method definition) means that protected method effectively cannot be overridden by subclasses. The redefinition of the method resets the protected access check to the subclass, so that instances of the parent class (or other subclasses) cannot call the method anymore.</p>
<p>Is the recommendation that using protected is just bad practice and should be avoided? Or is there a way to make the protected behavior aware of the parent method that is being overridden and keep the access check at the same level in the class hierarchy?</p>
<p>Example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Person</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">ssn</span><span class="p">)</span>
<span class="vi">@ssn</span> <span class="o">=</span> <span class="n">ssn</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">same?</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="n">tax_id</span> <span class="o">==</span> <span class="n">other</span><span class="p">.</span><span class="nf">tax_id</span>
<span class="k">end</span>
<span class="kp">protected</span>
<span class="k">def</span> <span class="nf">tax_id</span>
<span class="vi">@ssn</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">HappyPerson</span> <span class="o"><</span> <span class="no">Person</span>
<span class="k">def</span> <span class="nf">shout</span>
<span class="s1">'yay!'</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># corporations are people now</span>
<span class="k">class</span> <span class="nc">Corporation</span> <span class="o"><</span> <span class="no">Person</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">ein</span><span class="p">)</span>
<span class="vi">@ein</span> <span class="o">=</span> <span class="n">ein</span>
<span class="k">end</span>
<span class="kp">protected</span>
<span class="k">def</span> <span class="nf">tax_id</span>
<span class="vi">@ein</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">bob</span> <span class="o">=</span> <span class="no">Person</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s1">'000-00-0001'</span><span class="p">)</span>
<span class="n">sally</span> <span class="o">=</span> <span class="no">HappyPerson</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s1">'000-00-0002'</span><span class="p">)</span>
<span class="n">acme</span> <span class="o">=</span> <span class="no">Corporation</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s1">'00-0000001'</span><span class="p">)</span>
<span class="nb">puts</span> <span class="n">bob</span><span class="p">.</span><span class="nf">same?</span> <span class="n">bob</span> <span class="c1"># true</span>
<span class="nb">puts</span> <span class="n">bob</span><span class="p">.</span><span class="nf">same?</span> <span class="n">sally</span> <span class="c1"># false</span>
<span class="nb">puts</span> <span class="n">sally</span><span class="p">.</span><span class="nf">same?</span> <span class="n">bob</span> <span class="c1"># false</span>
<span class="nb">puts</span> <span class="n">acme</span><span class="p">.</span><span class="nf">same?</span> <span class="n">bob</span> <span class="c1"># false</span>
<span class="nb">puts</span> <span class="n">bob</span><span class="p">.</span><span class="nf">same?</span> <span class="n">acme</span> <span class="c1">#=> protected method `tax_id' called ... (NoMethodError)</span>
</code></pre> Ruby master - Misc #13787 (Open): The path to Ruby 3.x - would it be useful to have a separate th...https://bugs.ruby-lang.org/issues/137872017-08-07T21:09:14Zshevegen (Robert A. Heiler)shevegen@gmail.com
<p>Hello everyone but especially so the whole ruby-core team,</p>
<p>This is very long, so if you just want the short gist, please<br>
jump to the:</p>
<p>TL;DR line closer to the bottom.</p>
<p>Matz gave several presentations in the last ~3 years or so (and of course<br>
before that as well; but I am mostly focusing only on the 3 recent years,<br>
in particular because due to the path towards ruby 3.x).</p>
<p>I lately watched the presentation matz gave in Singapore and he made<br>
some references to things that will, quite likely, go into ruby 3.x,<br>
while he also said that there is a ton of work ahead - JIT compile<br>
strategies; the (optional, I guess) type system; better concurrency<br>
and so on and so forth. These are probably the big ideas - while this<br>
is nice, and I agree with comments such as "nobody minds if ruby gets<br>
faster" (everyone loves when things get done instantly rather than<br>
when you must wait), I myself am actually even more interested in<br>
smaller things. Even when they are incompatible with ruby 2.x, but<br>
I think that matz said that backwards-compatibility breaking changes<br>
may happen in ruby 3.x but not in ruby 2.x. Which is both good<br>
and bad - good because people do not have to rewrite stuff to<br>
run in ruby 2.x; bad if there are some habits or anything that<br>
isn't that great when writing software in ruby.</p>
<p>Sorry for my lengthy introduction so far - I wanted to explain the<br>
angle I am coming from here.</p>
<p>Now ...</p>
<p>I have wanted to make some smaller changes and suggestions towards<br>
ruby 3.x. And matz once said that the core team (and, well, matz,<br>
since he is the boss :D ) is open to ideas. In ruby 2.x, often the<br>
core team asks for use cases, which is fine - some proposals have<br>
not been thought through and others are purely theoretical; whereas<br>
others are also originating from some real use case. For ruby 3.x,<br>
it is obviously ... difficult to get a real use case out. :)</p>
<p>But one can actually try to make the argument about this or that<br>
in ruby 2.x not working very well, or being confusing.</p>
<p>For example, some days ago, I wanted to suggest a simplified<br>
API and usage for running external programs in ruby. We have<br>
system(), backticks, IO, popen, open3 ... and I do not know<br>
what else. All of which works slightly differently and it is,<br>
at the least to me, quite confusing sometimes. So I wanted<br>
to suggest a simplification... but I realized that this is<br>
not really a good topic for the ruby 2.x branch because I think<br>
that matz wants to retain compatibility, so such a proposal<br>
probably has not a big chance to be implemented. Perhaps for<br>
some minor changes, but I'd actually also suggest to get rid<br>
of some of the duplicate ways, while retaining flexibility<br>
still (so I'd say... system and backticks remain, and then<br>
perhaps only one or two more ways for more advanced use<br>
cases, via a simpler API than this strange ... open2 open3<br>
and what not...).</p>
<p>Anyway.</p>
<p>If you think this through then it probably does not fit much<br>
into "Features" for ruby 2.x because ruby 2.x will remain<br>
backwards compatible, I think.</p>
<p>But for ruby 3.x, it may it.</p>
<p>There are many more smaller ideas like this... for example, I'd<br>
like to see the warning/error situation be improved in ruby<br>
3.x in particular.</p>
<p>I'd also like case/when objects to become full objects and be<br>
passable/convertable ad-hoc into a hash or hash-like object,<br>
and re-used in different .rb files. (The workarounds I know<br>
about are usually to use a hash, with these aliases, but I<br>
found case/when menu to be so much more readable and nicer<br>
to use, especially as you can also use regexes).</p>
<p>And many more ideas like that!</p>
<p>But they all do not really fit into the "Bug" section, neither into<br>
the "Feature" subsection... they may fit somewhat into "Misc" but<br>
it's not a good category.</p>
<p>So, without any further explanation and further ado, here is the<br>
summary and proposal:</p>
<p>TL;DR - Would it be useful to have a separate thread here at the<br>
issue tracker, for discussions and issues and ideas related to<br>
ruby 3.x?</p>
<p>This can be kept primarily as an ideas section for the time being;<br>
at a later time, when ruby 3.x becomes the official ruby one day,<br>
the subsection can be closed and archived for, say, 3 years or so<br>
as read-only, before it would then be deleted (when ruby 3.x<br>
is eventually used more frequently than ruby 2.x, which I guess<br>
may take a few years ... there is a LOT of inertia in general,<br>
we can see this in perl, python etc..).</p>
<p>The reason why I think that this would be useful is because it<br>
could potentially foster some idea discussions. Getting early<br>
ideas in may be good, because ruby 3.x, while it is still<br>
quite far away I think (2020 or beyond?), getting ideas in early<br>
may help to see that they, or a variation, is considered for<br>
inclusion. Otherwise we then may have to wait for more years<br>
because ruby 3.x may be frozen and people would have to wait<br>
for ruby 4.x - this is the primary reason why I'd like to see<br>
a separate thread.</p>
<p>I can not say if this is useful or not to anyone else, and I<br>
can not say if this leads to more ideas or discussion for ruby<br>
3.x features (aside from the big ideas matz already mentioned<br>
several times before, such as better concurrency/guilds, JIT<br>
and speed improves in general or any optional type system -<br>
that's already quite a lot to work on, and all this in addition<br>
to mruby ... but I think ideas are not bad, even if it is not<br>
possible to implement several of them due to lack of time. When<br>
matz approves of an idea, who knows, perhaps someone else may<br>
see that the approved idea will be worked on).</p>
<p>Sorry for this lengthy note - feel free to close this at<br>
any moment in time, for any reason!</p> Ruby master - Misc #13634 (Open): NilClass is lying about respond_to?(:clone)https://bugs.ruby-lang.org/issues/136342017-06-06T08:12:46Zrovf (Ronald Fischer)ynnor@mm.st
<p>I put this under "Misc", because I'm not sure, whether this is a bug, a feature request, or maybe a deliberate (but for me obscure) decision in language design:</p>
<p>NilClass (and Fixnum) do not support clone. That's fine. However,</p>
<p>nil.respons_to?(:clone) returns true.</p>
<p>This means that we <em>can</em> ask nil to clone itself (we don't get a NoMethod error), it's just trying to do so throws an exception.</p>
<p>I stumbled over this problem when I had an collection of objects of different types, and wanted to apply :clone to some of them. My code went approximately like this:</p>
<p>object = collection[key]<br>
return object.respond_to?(:clone) ? object.clone : object</p>
<p>This doesn't work, if object is nil, true, false, a Symbol or a Fixnum, because all of them claim to respond to :clone.</p>
<p>Of course, there is a trivial workaround (I just have to rescue the exception), but I find this language design not really intuitive. I think there are two possibilites, how this can be made better:</p>
<p>(1) If we decide, that nil is not clonable (because there can be only one nil), then respond_to?(:clone) should IMHO simply be false.</p>
<p>(2) However, there might be even be a reason why :clone should be applicable. Note that the usual semantics of clone is to do a shallow copy (for instance, when we 'clone' a nested array). If we want to have a deep copy, the usual approach is Marshal.load(Marshal.dump(object)). Now the odd thing is that we can not "shallowly copy" nil, i.e. nil.clone is forbidden, but we can do a deep copy, i.e. Marshal.load(Marshal.dump(nil)) works. So, an alternative would be to have nil.clone simply return the identical object.</p>
<p>Both (1) seems to me a sound solution. The solution (2) has the drawback that we can't guarantee anymore that x.clone has a different object id than x, but is probably the behaviour a programmer would intuitively expect.</p> Ruby master - Misc #13497 (Open): Docs, code samples, Ripper examplehttps://bugs.ruby-lang.org/issues/134972017-04-23T04:27:52ZMSP-Greg (Greg L)
<p>I think it's fair to say that virtually all Ruby documentation today is created by doc generation systems based either on YARD or RDoc. Code samples/examples are common. YARD uses Ripper to parse samples for highlighting, I believe RDoc uses its own parser.</p>
<p>Although I recall previous RDoc parsers to be flexible as to code highlighting, but some seem to be similar to Ripper. Hence, if it can't be pasted into an .rb file and run, it won't highlight.</p>
<p>With many samples, this isn't an issue, but with samples that display multi-line output, there are two options -</p>
<ol>
<li>
<p>Comment the whole output section - this will always work, but all lines will render in the commment color.</p>
</li>
<li>
<p>Use an assignment - this will highlight the output (if desired).</p>
</li>
</ol>
<p>Ripper Examples --</p>
<p>RDoc - <a href="http://ruby-doc.org/stdlib-trunk/libdoc/ripper/rdoc/Ripper.html" class="external">ruby-doc.org</a></p>
<p>RDoc - <a href="https://docs.ruby-lang.org/en/trunk/Ripper.html" class="external">docs.ruby-lang.org</a></p>
<p>YARD - <a href="https://msp-greg.github.io/ruby_trunk/ripper/Ripper.html" class="external">msp-greg.github.io</a></p>
<p>Notice how the first two do not highlight the code sample in the overview, or the <code>.lex</code>, <code>.sexp</code>, or <code>.sexp_raw</code> methods.</p>
<p>I edited three source files for the highlighted output, it does require some kind of line similar to 'below is output, shown as assignment to allow highlighting'. The code in the sample doc is exactly as shown. I believe the two RDoc sites will highlight the code if redone in the style shown on msp-greg.github.io. I'd be happy to submit the changes if people find the highlighting helpful.</p> Ruby master - Misc #13209 (Open): fact.rb in ruby/sample variationshttps://bugs.ruby-lang.org/issues/132092017-02-13T00:59:46Zjzakiya (Jabari Zakiya)
<p>I was looking at some of the Sample files that come with Ruby and<br>
saw the example for doing factorials. It's an old example that I<br>
thought I could make simpler/faster. Below are the results.</p>
<p>Maybe upgrading to show the difference between coding idioms can<br>
be instructive to newer Ruby programmers.</p>
<pre><code>def fact(n)
return 1 if n == 0
f = 1
n.downto(1) do |i|
f *= i
end
return f
end
def fact1(n)
return 1 if n | 1 == 1 # if n 0 or 1
f = 2
n.downto(3) do |i|
f *= i
end
return f
end
def fact2(n)
return 1 if n | 1 == 1 # if n 0 or 1
(2..n).reduce(:*)
end
require 'benchmark/ips'
Benchmark.ips do |x|
x.report("original factorial") { fact 100 }
x.report("modified factorial") { fact1 100 }
x.report("enhanced factorial") { fact2 100 }
x.compare!
end
</code></pre>
<p>Timings using ruby-2.4.0 on Linux 64-bit, on I7 cpu system.</p>
<pre><code>2.4.0 :001 > load 'factversiontest.rb'
Warming up --------------------------------------
original factorial 4.501k i/100ms
modified factorial 4.594k i/100ms
enhanced factorial 5.271k i/100ms
Calculating -------------------------------------
original factorial 44.962k (± 4.2%) i/s - 225.050k in 5.015176s
modified factorial 46.288k (± 3.2%) i/s - 234.294k in 5.066948s
enhanced factorial 53.425k (± 3.1%) i/s - 268.821k in 5.036635s
Comparison:
enhanced factorial: 53424.9 i/s
modified factorial: 46288.0 i/s - 1.15x slower
original factorial: 44961.5 i/s - 1.19x slower
=> true
2.4.0 :002 >
</code></pre> Ruby master - Misc #12911 (Open): Translate docshttps://bugs.ruby-lang.org/issues/129112016-11-08T16:04:00Zsho-h (Sho Hashimoto)sho-h@netlab.jp
<p>translate doc/*.ja.rdoc</p>
<p>c.f. <a href="https://blade.ruby-lang.org/ruby-dev/47319">[ruby-dev:47319]</a></p> Ruby master - Misc #12751 (Open): Incompatibility of Ruby 3https://bugs.ruby-lang.org/issues/127512016-09-12T06:38:38Znaruse (Yui NARUSE)naruse@airemix.jp
<p>META ticket for Ruby 3's breakages</p>
<ul>
<li>Encoding on Windows
<ul>
<li>[Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: On Windows use UTF-8 as filesystem encoding (Closed)" href="https://bugs.ruby-lang.org/issues/12654">#12654</a>]</li>
<li>[Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Use UTF-8 encoding for ENV on Windows (Closed)" href="https://bugs.ruby-lang.org/issues/12650">#12650</a>]</li>
</ul>
</li>
</ul> Ruby master - Misc #12277 (Open): Coding rule: colum numberhttps://bugs.ruby-lang.org/issues/122772016-04-13T07:54:01Zko1 (Koichi Sasada)
<p>Eric proposed that code should be limited in 80 column.<br>
<a href="https://bugs.ruby-lang.org/issues/12236#note-1" class="external">https://bugs.ruby-lang.org/issues/12236#note-1</a></p>
<p>At today's developer's meeting, I asked how long column is suitable.</p>
<ul>
<li>declaration can over limitation.</li>
<li>logic should have some limitation (permit exceptional cases)</li>
</ul>
<p>This is an survey at today's meeting.</p>
<pre><code>Expected column limitation:
80 none
100 2 people
120 some people
over 120 only ko1
</code></pre> Ruby master - Misc #11783 (Open): Do you have any idea if you have a budgets?https://bugs.ruby-lang.org/issues/117832015-12-07T10:29:55Zko1 (Koichi Sasada)
<p>Do you have any idea about Ruby interpreter implementation to do with budgets?</p>
<a name="Background"></a>
<h1 >Background<a href="#Background" class="wiki-anchor">¶</a></h1>
<p>Now, we are summarizing many contributions from many people, organizations and companies.</p>
<p><a href="https://docs.google.com/document/d/1y1sQc40qeuWjF84rVrTmH-ogZ_iNGqU-RUSE8GDlRuk/edit?usp=sharing" class="external">https://docs.google.com/document/d/1y1sQc40qeuWjF84rVrTmH-ogZ_iNGqU-RUSE8GDlRuk/edit?usp=sharing</a></p>
<p>(please let me know if you know any other contributes)<br>
(sorry we wrote contributions especially for MRI, because we don't know)</p>
<p>The great recent news is we get new mac mini machine to run CI on El Capitan. We already have a mac mini machine running CI, but on Yosemite. So we can run CI on both Yosemite and El Capitan.</p>
<p>This new mac mini machine was sponsored by YassLab, Japanese small company.</p>
<p>At first, we ask Nihon-Ruby-no-Kai to prepare this machine, and Takahashi-san (chair man of this organization) tweet about it ("anyone can support it?"). Yasukawa-san, the president of YassLab answers "ok, we'll support it".</p>
<p>We learned that if we show requirements explicitly, anyone may help us.<br>
Listing is important.</p>
<a name="Any-idea"></a>
<h1 >Any idea?<a href="#Any-idea" class="wiki-anchor">¶</a></h1>
<p>Today's developers meeting, we had discussed about that and itemize some dreams.</p>
<blockquote>
<p>nurse: VPS severs for CI are welcome. Especially for Azure.<br>
ko1: travel fee (1,000,000 JPY?) for hackathon to gather MRI developers in one place<br>
ko1: physical machines for development and benchmarks (300,000 JPY)<br>
nobu: development machine (400,000 JPY) because he has several trouble on current machine.<br>
nurse: icc (and other softwares) to try.<br>
martin: grant project for MRI development topics<br>
ko1: education to grow other MRI developer (no estimation)</p>
</blockquote>
<p>Do you have any other idea?<br>
I'll show these list at RubyKaigi, and someone may consider to support us.</p>
<p>(IMO, maybe sponsoring nobu's machine is great contribution for Ruby worlds.<br>
Nobu will put companies logo stickers on his laptop)</p>
<p>Thanks,<br>
Koichi</p> Ruby master - Misc #11570 (Open): Clarify autoload chaining behavior https://bugs.ruby-lang.org/issues/115702015-10-06T16:52:25Zmwpastore (Mike Pastore)mike@oobak.org
<p>I've discovered a discrepancy between how MRI 2.1.7 and 2.2.3 handle autoload "chaining" (which I'll describe below) cf. RBX 2.5.8. I opened <a href="https://github.com/rubinius/rubinius/issues/3513" class="external">an issue</a> with them but the lead contributor of Rubinius is pushing back on me to clarify the expected behavior with you guys. Any guidance you can provide would be appreciated.</p>
<p>Essentially:</p>
<ul>
<li>File A autoloads <code>:Foo</code> from file B, and attempts to invoke methods on class <code>Foo</code>.</li>
<li>File B autoloads <code>:Foo</code> from file C, and attempts to reopen class <code>Foo</code> in order to define additional methods and attributes.</li>
<li>File C defines the base <code>Foo</code> class.</li>
</ul>
<p>In MRI 2.1.7 and 2.2.3, file A can see the methods defined in the base class defined in file C, as well as the extended methods and attributes added in file B. Both autoloads fire in the expected order and the composite class is computed and made available to the caller.</p>
<p>In RBX 2.5.8, file A can only see the extended methods and attributes defined in file B. Only the first autoload fires and the base class definition is never loaded or used.</p>
<p>Which is the correct behavior?</p> Ruby master - Misc #11355 (Open): Exceptions inheriting from Timeout::Error should behave the sam...https://bugs.ruby-lang.org/issues/113552015-07-15T16:59:01Zastratto (Stefano Tortarolo)stefano.tortarolo@gmail.com
<p>Bug <a class="issue tracker-1 status-6 priority-4 priority-default closed" title="Bug: "rescue Exception" rescues Timeout::ExitException (Rejected)" href="https://bugs.ruby-lang.org/issues/8730">#8730</a> addressed a common issue when using Timeout#timeout [*], but I think that the current behaviour is at the very least surprising.</p>
<p>Right now, exceptions provided to Timeout#timeout are rescuable from the inner block and that applies to Timeout::Error too.<br>
The confusing aspect is that there's no way to provide a custom exception that inherits from Timeout::Error and make it not rescuable by the inner block (i.e., <a class="issue tracker-1 status-2 priority-4 priority-default" title="Bug: Logger traps all exceptions; breaks Timeout (Assigned)" href="https://bugs.ruby-lang.org/issues/9115">#9115</a>).</p>
<p>Basically what I would expect is a way to provide a custom exception that's treated calling #catch on it in Timeout#timeout</p>
<pre><code># This could be applied to every exception that inherits from Timeout::Error
# but we need a different interface to provide it, in order to maintain the behaviour that a provided exception is rescuable
bt = Error.catch(message, &bl)
</code></pre>
<p>I'm filing this as Misc and not Bug exactly because reading the code it's expected behaviour, so I'm mainly trying to foster a conversation about whether there's a nice way to support both scenarios.</p>
<p>[*] I don't speak Japanese and I cannot fully trust Google Translate, so forgive me if I lost some fundamental concepts in that thread.</p> Ruby master - Misc #11295 (Open): Request for comments about error messageshttps://bugs.ruby-lang.org/issues/112952015-06-23T01:09:56Zko1 (Koichi Sasada)
<p>(This is not a proposal, bug reports)</p>
<p>Ruby shows error messages when something wrong.</p>
<p>There are several proposals to extend error messages.</p>
<ul>
<li><a href="https://github.com/charliesome/better_errors" class="external">https://github.com/charliesome/better_errors</a></li>
<li><a href="https://github.com/yuki24/did_you_mean" class="external">https://github.com/yuki24/did_you_mean</a></li>
<li><a href="https://github.com/ko1/pretty_backtrace" class="external">https://github.com/ko1/pretty_backtrace</a></li>
</ul>
<p>And some requests.</p>
<ul>
<li>Reverse backtrace and show error messages at the bottom (to avoid scroll up terminal)</li>
<li>Translation error messages to other languages</li>
</ul>
<p>If you have any idea, please tell us.<br>
We can consider about Ruby's error message APIs to realize your ideas.<br>
(I can't guarantee we can implement your ideas :p)</p> Ruby master - Misc #10983 (Open): Why blocks make Ruby methods 439% slower ?https://bugs.ruby-lang.org/issues/109832015-03-19T09:03:44ZSega100500 (Сергей Е)Sergey.V.Ezhov@gmail.com
<p><a href="https://www.omniref.com/ruby/2.2.0/symbols/Proc/yield#annotation=4087638&line=711&hn=1" class="external">https://www.omniref.com/ruby/2.2.0/symbols/Proc/yield#annotation=4087638&line=711&hn=1</a></p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'benchmark/ips'</span>
<span class="k">def</span> <span class="nf">block_call</span><span class="p">(</span><span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="n">block</span><span class="p">.</span><span class="nf">call</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">just_yield</span>
<span class="k">yield</span>
<span class="k">end</span>
<span class="no">Benchmark</span><span class="p">.</span><span class="nf">ips</span> <span class="k">do</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="nf">report</span><span class="p">(</span><span class="s2">"call"</span><span class="p">)</span> <span class="k">do</span>
<span class="n">block_call</span> <span class="p">{</span> <span class="mi">1</span> <span class="o">+</span> <span class="mi">1</span> <span class="p">}</span>
<span class="k">end</span>
<span class="n">x</span><span class="p">.</span><span class="nf">report</span><span class="p">(</span><span class="s2">"just yield"</span><span class="p">)</span> <span class="k">do</span>
<span class="n">just_yield</span> <span class="p">{</span> <span class="mi">1</span> <span class="o">+</span> <span class="mi">1</span> <span class="p">}</span>
<span class="k">end</span>
<span class="n">x</span><span class="p">.</span><span class="nf">compare!</span>
<span class="k">end</span>
</code></pre>
<p>I run on Ruby 2.2.1</p>
<pre><code>Calculating -------------------------------------
call 40.754k i/100ms
just yield 69.031k i/100ms
-------------------------------------------------
call 814.929k (± 4.0%) i/s - 4.075M
just yield 2.871M (±25.1%) i/s - 12.909M
Comparison:
just yield: 2871127.3 i/s
call: 814929.3 i/s - 3.52x slower
</code></pre> Ruby master - Misc #10791 (Open): [PATCH 1/1] Remove unnecessary passing value from doc for Obser...https://bugs.ruby-lang.org/issues/107912015-01-27T19:43:48Zgogotanaka (Kazuki Tanaka)mail@tanakakazuki.com
<p>Hi, when reading doc for Observable, I notice little unnecessary code which may cause little confusion in example.</p>
<p>take your time.</p>
<p>gogo.</p>