Ruby Issue Tracking System: Issueshttps://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112024-03-16T10:21:57ZRuby Issue Tracking System
Redmine Ruby master - Bug #20342 (Open): Top level `public`, `private` and `ruby2_keywords` do not work i...https://redmine.ruby-lang.org/issues/203422024-03-16T10:21:57Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<p>With this file:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># load.rb</span>
<span class="kp">public</span> <span class="k">def</span> <span class="nf">f</span> <span class="o">=</span> <span class="ss">:ok</span>
</code></pre>
<p>It is OK when <code>require</code>d.</p>
<pre><code data-language="sh-session">$ ruby -r ./load.rb -e 'p f'
:ok
</code></pre>
<p>Simple <code>load</code> is OK too.</p>
<pre><code data-language="sh-session">$ ruby -e 'load ARGV[0]; p f' load.rb
:ok
</code></pre>
<p>Wrapped <code>load</code> fails.</p>
<pre><code data-language="sh-session">$ ruby -e 'load ARGV[0], true' load.rb
load.rb:1:in 'public': undefined method 'f' for class 'Object' (NameError)
public def f = :ok
^^^^^^
from load.rb:1:in '<top (required)>'
from -e:1:in 'Kernel#load'
from -e:1:in '<main>'
</code></pre> Ruby master - Misc #20320 (Open): Using OSU Open Source Lab native ppc64le/s390x CI services trig...https://redmine.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 - Bug #20299 (Open): Tracepoint staying enable after a disablehttps://redmine.ruby-lang.org/issues/202992024-02-26T01:06:28ZMaxLap (Maxime Lapointe)hunter_spawn@hotmail.com
<p>Problem is present in Ruby 3.2.2, 3.2.3, 3.3.0. Didn't check before.</p>
<p>It seems that TracePoint can sometime be "stuck" enabled after using disabled once on it.</p>
<p>Here is a reproduction step using a "check speed" method that just does some work and print out how long it takes. This makes it pretty clear when TracePoint was on.</p>
<p>Put this in a Ruby file:</p>
<pre><code>def check_speed(msg)
t1 = Time.now.to_f
a = 0
1000000.times { |i|
a += 10
}
t2 = Time.now.to_f
puts "#{t2-t1} - #{msg}"
end
check_speed("before") # fast
trace = TracePoint.new(:line) {}
trace.enable
check_speed("after enable") # slow
trace.enable {
check_speed("in block enable") # slow
}
check_speed("after block enable") # slow
trace.disable
check_speed("after disable") # slow !!!!
trace.disable
check_speed("after disable again") # fast !!!!
# And yet, using enable multiple time doesn't have a "counter" or similar
trace.enable
trace.enable
trace.enable
check_speed("after triple enable") # slow
trace.disable
check_speed("after single disable") # fast
</code></pre>
<p>Running the file, we get this:</p>
<pre><code>$ ruby -v
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-linux]
$ ruby local.rb
0.03473854064941406 - before
0.18935227394104004 - after enable
0.17757630348205566 - in block enable
0.18320131301879883 - after block enable
0.1818866729736328 - after disable
0.03412747383117676 - after disable again
0.18405628204345703 - after triple enable
0.033496856689453125 - after single disable
</code></pre>
<p>The first "after disable" should probably have been fast. If it's possible to have multiple nested enable/disable, then one would instead assume that after the last "single disable", things would still be slow.</p>
<p>Note: This code patterns comes directly for a ruby/spec: ctrl+f for "enables trace object on calling with a block if it was already enabled"</p>
<p>I note that in Ruby 3.2, the timing are a lot less similar. I don't know why. It would seem like TracePoint got slower in Ruby 3.3.0. Is that worth checking out / making a distincct bug for?</p>
<pre><code>$ rvm use 3.2.3
Using /home/max/.rvm/gems/ruby-3.2.3
$ ruby local.rb
0.03246927261352539 - before
0.07910513877868652 - after enable
0.10309600830078125 - in block enable
0.12397646903991699 - after block enable
0.07114601135253906 - after disable
0.028218746185302734 - after disable again
0.12534689903259277 - after triple enable
0.02810525894165039 - after single disable
</code></pre> Ruby master - Misc #20240 (Open): Unable to build ruby 3.1.0 on macOS when shared due to dylibs (...https://redmine.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://redmine.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 - Bug #20179 (Open): `--with-ruby-version` configure option is not correctly applied ...https://redmine.ruby-lang.org/issues/201792024-01-12T13:18:55Zvo.x (Vit Ondruch)v.ondruch@tiscali.cz
<p>I am trying to configure ruby using <code>--with-ruby-version=ruby3.3</code>. Here is the configure output:</p>
<pre><code>$ /builddir/build/BUILD/ruby-3.3.0/configure --build=x86_64-redhat-linux-gnu --host=x86_64-redhat-linux-gnu --program-prefix= --disable-dependency-tracking --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib64 --libexecdir=/usr/libexec --localstatedir=/var --runstatedir=/run --sharedstatedir=/var/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-compress-debug-sections=no --disable-rpath --enable-mkmf-verbose --enable-shared --with-ruby-version=ruby3.3 --enable-yjit
... snip ...
---
Configuration summary for ruby version 3.3.0
* Installation prefix: /usr
* exec prefix: /usr
* arch: x86_64-linux
* site arch: ${arch}
* RUBY_BASE_NAME: ruby
* enable shared: yes
* ruby lib prefix: ${libdir}/${RUBY_BASE_NAME}
* site libraries path: ${rubylibprefix}/${sitearch}
* vendor path: ${rubylibprefix}/vendor_ruby
* target OS: linux
* compiler: gcc
* with thread: pthread
* with coroutine: amd64
* enable shared libs: yes
* dynamic library ext: so
* CFLAGS: ${optflags} ${debugflags} ${warnflags}
* LDFLAGS: -L. -Wl,-z,relro -Wl,--as-needed \
-Wl,-z,pack-relative-relocs -Wl,-z,now \
-specs=/usr/lib/rpm/redhat/redhat-hardened-ld \
-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 \
-Wl,--build-id=sha1 -fstack-protector-strong \
-rdynamic -Wl,-export-dynamic -Wl,--no-as-needed
* DLDFLAGS: -Wl,-z,relro -Wl,--as-needed \
-Wl,-z,pack-relative-relocs -Wl,-z,now \
-specs=/usr/lib/rpm/redhat/redhat-hardened-ld \
-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 \
-Wl,--build-id=sha1
* optflags: -O3 -fno-fast-math
* debugflags: -ggdb3
* warnflags: -Wall -Wextra -Wdeprecated-declarations \
-Wdiv-by-zero -Wduplicated-cond \
-Wimplicit-function-declaration -Wimplicit-int \
-Wpointer-arith -Wwrite-strings \
-Wold-style-definition -Wimplicit-fallthrough=0 \
-Wmissing-noreturn -Wno-cast-function-type \
-Wno-constant-logical-operand -Wno-long-long \
-Wno-missing-field-initializers \
-Wno-overlength-strings \
-Wno-packed-bitfield-compat \
-Wno-parentheses-equality -Wno-self-assign \
-Wno-tautological-compare -Wno-unused-parameter \
-Wno-unused-value -Wsuggest-attribute=format \
-Wsuggest-attribute=noreturn -Wunused-variable \
-Wmisleading-indentation -Wundef
* strip command: strip -S -x
* install doc: rdoc
* YJIT support: yes
* RJIT support: yes
* man page type: doc
---
</code></pre>
<p>However, the option is not applied consistently, especially the <code>rubyhdrdir</code> stands out:</p>
<pre><code>$ find . -name \*ruby3.3\*
./usr/lib64/ruby/ruby3.3
./usr/lib64/ruby/site_ruby/ruby3.3
./usr/lib64/ruby/vendor_ruby/ruby3.3
./usr/lib64/ruby/gems/ruby3.3
./usr/lib64/ruby/gems/ruby3.3/extensions/x86_64-linux/ruby3.3
./usr/include/ruby-ruby3.3
./usr/share/ri/ruby3.3
</code></pre>
<p>The correct path should be IMHO <code>./usr/include/ruby3.3</code>. I can likely workaround it by <code>--with-rubyhdrdir</code>, but I think this should behave consistently.</p> Ruby master - Bug #20081 (Open): Transfered Fiber doesn't return to Fiber that started ithttps://redmine.ruby-lang.org/issues/200812023-12-23T17:44:10Zrmosolgo (Robert Mosolgo)rdmosolgo@gmail.com
<p>Hi! I'm trying to figure out how to make sure that Fibers started with <code>.transfer</code> end up <em>terminated</em>, not just suspended. (If they're suspended, Rails thinks they're still alive, and they continue to hold onto database connections, see: <a href="https://github.com/rmosolgo/graphql-ruby/issues/4739#issuecomment-1866930914" class="external">https://github.com/rmosolgo/graphql-ruby/issues/4739#issuecomment-1866930914</a>.)</p>
<p>So, I'm looking for way to make sure that any Fiber I start with <code>.transfer</code> will be properly terminated. But what I noticed is that when a transfer-based Fiber terminates, it gives control back to the top-most Fiber, not the Fiber which transfered to it. Is this intended? Here's a script to replicate the issue:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">manager</span> <span class="o">=</span> <span class="no">Fiber</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">parent</span> <span class="o">=</span> <span class="no">Fiber</span><span class="p">.</span><span class="nf">current</span>
<span class="n">worker</span> <span class="o">=</span> <span class="no">Fiber</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="nb">puts</span> <span class="s2">"2. Begin Worker"</span>
<span class="n">parent</span><span class="p">.</span><span class="nf">transfer</span>
<span class="nb">puts</span> <span class="s2">"4. End Worker"</span>
<span class="k">end</span>
<span class="nb">puts</span> <span class="s2">"1. Transfer 1"</span>
<span class="n">worker</span><span class="p">.</span><span class="nf">transfer</span>
<span class="nb">puts</span> <span class="s2">"3. Transfer 2"</span>
<span class="n">worker</span><span class="p">.</span><span class="nf">transfer</span>
<span class="nb">puts</span> <span class="s2">"5. Finished manager"</span>
<span class="k">end</span>
<span class="n">manager</span><span class="p">.</span><span class="nf">transfer</span>
<span class="nb">puts</span> <span class="s2">"6. Finished script"</span>
</code></pre>
<p>I expect the steps to print in order:</p>
<pre><code>1. Transfer 1
2. Begin Worker
3. Transfer 2
4. End Worker
5. Finished manager
6. Finished script
</code></pre>
<p>But instead, <code>5. ...</code> is skipped:</p>
<pre><code>1. Transfer 1
2. Begin Worker
3. Transfer 2
4. End Worker
6. Finished script
</code></pre>
<p>I think that's because my <code>worker</code> fiber terminates and passes control back to the top-level Fiber.</p>
<p>Should it have passed control back to the <code>manager</code>? Or is there another way to make sure <code>worker</code> is terminated, and <code>manager</code> gets control?</p> Ruby master - Misc #20013 (Open): Travis CI statushttps://redmine.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 - Bug #19986 (Open): Win32: `HOME` is set to just `HOMEDRIVE` if `HOMEPATH` is unsethttps://redmine.ruby-lang.org/issues/199862023-11-05T03:15:02Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<pre><code>$ env -u HOME -u USERPROFILE -u HOMEPATH HOMEDRIVE=no/such/home ./miniruby.exe -e 'p ENV["HOME"], Dir.home'
"no/such/home"
"no/such/home"
</code></pre>
<p><code>HOMEDRIVE</code> should be ignored without <code>HOMEPATH</code>, and <code>HOME</code> should fallback to <code>CSIDL_PROFILE</code>.</p> Ruby master - Feature #19931 (Open): to_int is not for implicit conversion?https://redmine.ruby-lang.org/issues/199312023-10-17T17:39:44ZDan0042 (Daniel DeLorme)
<p>While reviewing some implicit vs explicit conversion concepts, I discovered that arithmetic operations do not perform the implicit conversion I expected from #to_int</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">o</span> <span class="o">=</span> <span class="no">Object</span><span class="p">.</span><span class="nf">new</span>
<span class="k">def</span> <span class="nc">o</span><span class="o">.</span><span class="nf">to_int</span><span class="p">;</span> <span class="mi">1</span><span class="p">;</span> <span class="k">end</span>
<span class="mi">1</span> <span class="o">+</span> <span class="n">o</span> <span class="c1">#TypeError</span>
</code></pre>
<p>I understand there's the whole #coerce thing for numbers, but I had expected #to_int to fit neatly into this and cause the object to be implicitly coerced to Integer.</p>
<p>So basically I thought that #to_i was for explicit conversion and #to_int for implicit conversion; is that not the case?<br>
Most of the internet seems to think that (to_int : to_i) relationship is like (to_str : to_s). But I can't seems to find authoritative documentation on the topic.</p> Ruby master - Feature #19915 (Open): URI::HTTP.build accepts user: and password: keyboard argumen...https://redmine.ruby-lang.org/issues/199152023-10-08T23:10:10Zpostmodern (Hal Brodigan)postmodern.mod3@gmail.com
<p>I noticed that <code>URI::HTTP.build</code> accepts the <code>user:</code> and <code>password:</code> keyword arguments, but does not actually set the <code>user</code> or <code>password</code> attributes of the built URI object. It does however correctly accept a <code>userinfo:</code> keyword argument.</p>
<a name="Steps-To-Reproduce"></a>
<h2 >Steps To Reproduce<a href="#Steps-To-Reproduce" class="wiki-anchor">¶</a></h2>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">uri</span> <span class="o">=</span> <span class="no">URI</span><span class="o">::</span><span class="no">HTTP</span><span class="p">.</span><span class="nf">build</span><span class="p">(</span><span class="ss">user: </span><span class="s1">'bob'</span><span class="p">,</span> <span class="ss">password: </span><span class="s1">'secret'</span><span class="p">,</span> <span class="ss">host: </span><span class="s1">'example.com'</span><span class="p">,</span> <span class="ss">path: </span><span class="s1">'/foo'</span><span class="p">)</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">user</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">password</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">to_s</span>
</code></pre>
<a name="Expected-Results"></a>
<h3 >Expected Results<a href="#Expected-Results" class="wiki-anchor">¶</a></h3>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">uri</span><span class="p">.</span><span class="nf">user</span>
<span class="c1"># => "bob"</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">password</span>
<span class="c1"># => "secret"</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">to_s</span>
<span class="c1"># => "http://bob:secret@example.com/foo"</span>
</code></pre>
<a name="Actual-Results"></a>
<h3 >Actual Results<a href="#Actual-Results" class="wiki-anchor">¶</a></h3>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">uri</span><span class="p">.</span><span class="nf">user</span>
<span class="c1"># => nil</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">password</span>
<span class="c1"># => nil</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">to_s</span>
<span class="c1"># => "http://example.com/foo"</span>
</code></pre> Ruby master - Bug #19831 (Open): warning message of linker with macOS Sonoma betahttps://redmine.ruby-lang.org/issues/198312023-08-04T09:21:01Zhsbt (Hiroshi SHIBATA)hsbt@ruby-lang.org
<p>Xcode 15 beta and macOS Sonoma beta show the following warnings with <code>make</code></p>
<pre><code>(snip)
linking miniruby
ld: warning: ignoring duplicate library '-lpthread'
miniruby: replacing existing signature
exe/ruby: replacing existing signature
builtin_binary.inc updated
compiling builtin.c
linking static-library libruby.3.3-static.a
linking ruby
ld: warning: ignoring duplicate library '-lgmp'
ld: warning: ignoring duplicate library '-ldl'
ld: warning: ignoring duplicate library '-lobjc'
ld: warning: ignoring duplicate library '-lpthread'
ld: warning: ignoring duplicate library '-lpthread'
(snip)
</code></pre>
<p>I'm not investigate that yet. It may be caused by <code>ld-prime</code> that is new linker of macOS platform.</p>
<pre><code>$ pkgutil --pkg-info=com.apple.pkg.CLTools_Executables
package-id: com.apple.pkg.CLTools_Executables
version: 15.0.0.0.1.1690355577
volume: /
location: /
install-time: 1690967267
</code></pre> Ruby master - Bug #19756 (Open): URI::HTTP.build does not accept a host of `_gateway`, but `URI.p...https://redmine.ruby-lang.org/issues/197562023-07-04T02:11:27Zpostmodern (Hal Brodigan)postmodern.mod3@gmail.com
<p>I noticed a difference in behavior between <code>URI::HTTP.build</code> and <code>URI.parse</code>. <code>URI::HTTP.build</code> will not accept <code>host:</code> value of <code>_gateway</code>, but <code>URI.parse</code> will.</p>
<a name="Steps-To-Reproduce"></a>
<h2 >Steps To Reproduce<a href="#Steps-To-Reproduce" class="wiki-anchor">¶</a></h2>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">URI</span><span class="o">::</span><span class="no">HTTP</span><span class="p">.</span><span class="nf">build</span><span class="p">(</span><span class="ss">host: </span><span class="s2">"_gateway"</span><span class="p">)</span>
</code></pre>
<p>vs.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">URI</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="s2">"http://_gateway"</span><span class="p">)</span>
</code></pre>
<a name="Expected-Results"></a>
<h3 >Expected Results<a href="#Expected-Results" class="wiki-anchor">¶</a></h3>
<p>Both raise the same exception, or return the same URI object.</p>
<a name="Actual-Results"></a>
<h3 >Actual Results<a href="#Actual-Results" class="wiki-anchor">¶</a></h3>
<pre><code>URI::HTTP.build(host: "_gateway")
/usr/share/ruby/uri/generic.rb:601:in `check_host': bad component(expected host component): _gateway (URI::InvalidComponentError)
from /usr/share/ruby/uri/generic.rb:640:in `host='
from /usr/share/ruby/uri/generic.rb:673:in `hostname='
from /usr/share/ruby/uri/generic.rb:190:in `initialize'
from /usr/share/ruby/uri/generic.rb:136:in `new'
from /usr/share/ruby/uri/generic.rb:136:in `build'
from /usr/share/ruby/uri/http.rb:61:in `build'
from (irb):2:in `<main>'
from /usr/local/share/gems/gems/irb-1.7.0/exe/irb:9:in `<top (required)>'
from /usr/local/bin/irb:25:in `load'
from /usr/local/bin/irb:25:in `<main>'
</code></pre>
<pre><code>URI.parse("https://_gateway")
# => #<URI::HTTPS https://_gateway>
</code></pre>
<a name="Additional-Information"></a>
<h2 >Additional Information<a href="#Additional-Information" class="wiki-anchor">¶</a></h2>
<pre><code>$ gem list uri
uri (default: 0.12.1)
</code></pre> Ruby master - Feature #19604 (Open): XOAUTH2 support in net-pophttps://redmine.ruby-lang.org/issues/196042023-04-17T15:28:41Zcheez331 (Alessio Cosenza)
<p>I would like to add support to XOAUTH2 in the net-pop library.<br>
I've opened a PR on the GitHub repo and I would like to gather some feedback and having it reviewed/merged.</p>
<p>The PR is here: <a href="https://github.com/ruby/net-pop/pull/16" class="external">https://github.com/ruby/net-pop/pull/16</a> and the documentation about XOAUTH2 for pop3 can be found:</p>
<ul>
<li><a href="https://www.rfc-editor.org/rfc/rfc1734" class="external">https://www.rfc-editor.org/rfc/rfc1734</a></li>
<li><a href="https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth" class="external">https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth</a></li>
</ul>
<p>Thanks!</p> Ruby master - Bug #19266 (Open): URI::Generic should use URI::RFC3986_PARSER instead of URI::DEFA...https://redmine.ruby-lang.org/issues/192662022-12-26T18:52:36Zgareth (Gareth Adams)
<p>In June 2014, <a href="https://github.com/ruby/ruby/commit/bb83f32dc3e0424d25fa4e55d8ff32b061320e41" class="external"><code>uri/common</code> was updated</a> to introduce a RFC3986-compliant parser (<code>URI::RFC3986_PARSER</code>) as an alternative to the previous RFC2396 parser, and common methods like <code>URI()</code> were updated to use that new parser by default. The only methods in <code>common</code> not updated were <a href="https://github.com/ruby/ruby/blob/28a17436503c3c4cb7a35b423a894b697cd80da9/lib/uri/common.rb#L233-L297" class="external"><code>URI.extract</code> and <code>URI.regexp</code></a> which are marked as obsolete. (The old parser was kept in the <code>DEFAULT_PARSER</code> constant despite it not being the default for those methods, presumably for backward compatibility.)</p>
<p>However, similar <a href="https://github.com/ruby/ruby/blob/28a17436503c3c4cb7a35b423a894b697cd80da9/lib/uri/generic.rb#L169-L175" class="external">methods called on <code>URI::Generic</code></a> were never updated to use this new parser. This means that methods like <code>URI::Generic.build</code> fail when given input that succeeds normally, and this also affects subclasses like URI::HTTP:</p>
<pre><code>$ pry -r uri -r uri/common -r uri/generic
[1] pry(main)> URI::Generic.build(host: "underscore_host.example")
URI::InvalidComponentError: bad component(expected host component): underscore_host.example
from /Users/gareth/.asdf/installs/ruby/3.1.3/lib/ruby/3.1.0/uri/generic.rb:591:in `check_host'
[2] pry(main)> URI::HTTP.build(host: "underscore_host.example")
URI::InvalidComponentError: bad component(expected host component): underscore_host.example
from /Users/gareth/.asdf/installs/ruby/3.1.3/lib/ruby/3.1.0/uri/generic.rb:591:in `check_host'
[3] pry(main)> URI("http://underscore_host.example")
=> #<URI::HTTP http://underscore_host.example>
</code></pre>
<p><code>URI::Generic.new</code> allows a configurable <code>parser</code> positional argument to override the class' default parser, but other factory methods like <code>.build</code> don't allow this override.</p>
<p>Arguably this doesn't cause problems because at least in the case above, the URI can be built with the polymorphic constructor, but having the option to build URIs from explicit named parts is useful, and leaving the outdated functionality in the <code>Generic</code> class is ambiguous. It's possible that the whole Generic class and its subclasses aren't intended to be used directly how I'm intending here, but there's nothing I could see that suggested this is the case.</p>
<p>I'm not aware of the entire list of differences between RFC2396 and RFC3986. The relevant difference here is that in RFC2396 an individual segment of a host (<a href="https://www.rfc-editor.org/rfc/rfc2396#section-3.2.2" class="external"><code>domainlabel</code>s</a>) could only be <code>alphanum | alphanum *( alphanum | "-" ) alphanum</code>, whereas RFC3986 allows <a href="https://www.rfc-editor.org/rfc/rfc3986#page-13" class="external">hostnames</a> to include any of <code>ALPHA / DIGIT / "-" / "." / "_" / "~"</code>. It's possible that other differences might cause issues for developers, but since this has gone over 8 years without anyone else caring about this, this is definitely not especially urgent.</p> Ruby master - Bug #19157 (Open): URI bad component validation can be trickedhttps://redmine.ruby-lang.org/issues/191572022-11-28T23:46:13Zstraight-shoota (Johannes Müller)
<p><code>URI::HTTP</code> checks the validity of the URI components. For example, the path of a URI with authority component must be either empty or start with a slash.</p>
<p>This validation applies on the <code>.build</code> constructor as well as on the <code>path</code> setter.<br>
But it can be tricked when setting an empty authority component and scheme before setting a relative path, and then setting the authority and scheme again.<br>
This produces an invalid and incorrect URI.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s2">"uri"</span>
<span class="n">uri</span> <span class="o">=</span> <span class="no">URI</span><span class="o">::</span><span class="no">HTTP</span><span class="p">.</span><span class="nf">build</span><span class="p">({})</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">scheme</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">path</span> <span class="o">=</span> <span class="s2">"resource"</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">host</span> <span class="o">=</span> <span class="s2">"example.com"</span> <span class="c1"># this should raise URI::InvalidComponentError</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">scheme</span> <span class="o">=</span> <span class="s2">"http"</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">to_s</span> <span class="c1"># => "http://example.comresource"</span>
</code></pre> Ruby master - Misc #19121 (Open): Time: utc offset argument's formats "+/-HH", "+/-HHMM", "+/-HHM...https://redmine.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://redmine.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 - Feature #19064 (Open): UDPSocket#bind does not take AddrInfo, despite documentation...https://redmine.ruby-lang.org/issues/190642022-10-17T00:50:44Zmcr (Michael Richardson)mcr@sandelman.ca
<p><a href="https://docs.ruby-lang.org/en/master/Socket.html#method-i-bind" class="external">https://docs.ruby-lang.org/en/master/Socket.html#method-i-bind</a> says that this code should work:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'socket'</span>
<span class="c1"># use Addrinfo</span>
<span class="n">socket</span> <span class="o">=</span> <span class="no">Socket</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">:INET</span><span class="p">,</span> <span class="ss">:STREAM</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">socket</span><span class="p">.</span><span class="nf">bind</span><span class="p">(</span><span class="no">Addrinfo</span><span class="p">.</span><span class="nf">tcp</span><span class="p">(</span><span class="s2">"127.0.0.1"</span><span class="p">,</span> <span class="mi">2222</span><span class="p">))</span>
<span class="nb">p</span> <span class="n">socket</span><span class="p">.</span><span class="nf">local_address</span> <span class="c1">#=> #<Addrinfo: 127.0.0.1:2222 TCP></span>
</code></pre>
<p>and it does, but UDPSocket does <em>not</em> like Addrinfo:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">socket</span> <span class="o">=</span> <span class="no">UDPSocket</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">Socket</span><span class="o">::</span><span class="no">AF_INET6</span><span class="p">)</span>
<span class="n">ai</span><span class="o">=</span><span class="no">Addrinfo</span><span class="p">.</span><span class="nf">udp</span><span class="p">(</span><span class="s2">"127.0.0.1"</span><span class="p">,</span> <span class="mi">2224</span><span class="p">)</span>
<span class="n">socket</span><span class="p">.</span><span class="nf">bind</span><span class="p">(</span><span class="n">ai</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</code></pre>
<p>A reason to use an Addrinfo rather than a string is because it came from, for instance, Socket.getifaddrs, and might have scope and other information attached, like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1">#<Addrinfo: fe80::f58e:d5ea:41e0:2555%eth0></span>
</code></pre>
<p>Seen on versions back to 2.6.6, but tested with ruby-head to be sure.</p> Ruby master - Feature #19022 (Open): Use __builtin_ppc_get_timebase on POWER with clanghttps://redmine.ruby-lang.org/issues/190222022-09-26T22:02:06Zpkubaj (Piotr Kubaj)
<p>Use __builtin_ppc_get_timebase on POWER with clang.<br>
<a href="https://github.com/ruby/ruby/pull/5856" class="external">https://github.com/ruby/ruby/pull/5856</a></p> Ruby master - Bug #18947 (Open): Unexpected Errno::ENAMETOOLONG on Windowshttps://redmine.ruby-lang.org/issues/189472022-07-29T07:08:19Zinversion (Yura Babak)
<p>On Windows 10, I am working on a script to copy a complex folder structure.</p>
<p>Pathname and FileUtils work fine for me until there is a folder with a <strong>very long path</strong> (>260 chars).</p>
<p>Normally you cannot access such a folder with Ruby.<br>
The next operations will raise <code>Errno::ENOENT</code></p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Pathname</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">300</span><span class="n">_chars_path</span><span class="p">).</span><span class="nf">children</span>
<span class="no">FileUtils</span><span class="p">.</span><span class="nf">mkpath</span><span class="p">(</span><span class="mi">300</span><span class="n">_chars_path</span><span class="p">)</span>
</code></pre>
<p>But there is a way in Windows to remove the MAX_PATH limitation.<br>
You can find a small .reg file in this article:<br>
<a href="https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry" class="external">https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry</a></p>
<p>After changing this system option, things start to work strangely in Ruby.</p>
<p>This will now raise <code>Errno::ENAMETOOLONG</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Pathname</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">300</span><span class="n">_chars_path</span><span class="p">).</span><span class="nf">children</span>
</code></pre>
<p>But at the same time, you can create a folder with such a long path and write-read a file in it</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">FileUtils</span><span class="p">.</span><span class="nf">mkpath</span><span class="p">(</span><span class="mi">300</span><span class="n">_chars_path</span><span class="p">)</span>
<span class="n">file</span> <span class="o">=</span> <span class="no">Pathname</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">300</span><span class="n">_chars_path</span><span class="o">+</span><span class="s1">'/file.txt'</span><span class="p">)</span>
<span class="n">file</span><span class="p">.</span><span class="nf">write</span> <span class="s1">'oooooooooo'</span>
<span class="nb">puts</span> <span class="no">Pathname</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">300</span><span class="n">_chars_path</span><span class="o">+</span><span class="s1">'/file.txt'</span><span class="p">).</span><span class="nf">read</span>
</code></pre>
<p>So you can work with individual items but attempts to list such folders' content fail (<code>.children</code>, <code>.glob</code>, <code>.copy</code>, etc).<br>
In my case, deep <code>.glob</code> is broken for all the parent folders of that deep long-path folder ((</p>
<p>The only way I found for listing is</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'win32ole'</span>
<span class="n">fso</span> <span class="o">=</span> <span class="no">WIN32OLE</span><span class="p">.</span><span class="nf">new</span> <span class="s1">'Scripting.FileSystemObject'</span>
<span class="k">for</span> <span class="n">file</span> <span class="k">in</span> <span class="n">fso</span><span class="o">.</span><span class="no">GetFolder</span><span class="p">(</span><span class="mi">300</span><span class="n">_chars_path</span><span class="p">).</span><span class="nf">files</span>
<span class="n">file</span><span class="p">.</span><span class="nf">name</span>
<span class="n">file</span><span class="p">.</span><span class="nf">path</span><span class="p">.</span><span class="nf">length</span>
<span class="k">end</span>
</code></pre>
<p>But using this workaround breaks all my code workflow built on top of Pathname and FileUtils ((.</p>
<p>So for me, it looks like some operations with long-path folders are not working just because in Ruby there is a check for the path length and not a real operation problem. And in some places (see .mkpath) there is no such check and all works fine.</p>
<p>Also notice that other applications on Windows have no problems with long-path folders (like Total Commander).</p>
<p>Please consider reviewing if we really need to raise <code>Errno::ENAMETOOLONG</code> if the <code>LongPathsEnabled</code> option is enabled in the Windows registry.</p> Ruby master - Misc #18840 (Open): Top-level #using and other methods docshttps://redmine.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 - Bug #18794 (Open): Windows - intermittent SEGV TestObjSpace#test_reachable_objects_...https://redmine.ruby-lang.org/issues/187942022-05-20T17:19:08ZMSP-Greg (Greg L)
<p>Test runs in retry, generates the following (removed path from x64-ucrt-ruby320.dll). mswin build runs it as a single test, I don't believe it's failed.</p>
<pre><code> 1) Failure:
TestObjSpace#test_reachable_objects_during_iteration Line: 145
assert_separately failed with error message
pid 70572 exit 3
| -:8: [BUG] Unnormalized Fixnum value 0x0000023f8eeb2119
| ruby 3.2.0dev (2022-05-20T15:42:07Z master 11336c7ddb) [x64-mingw-ucrt]
|
| -- Control frame information -----------------------------------------------
| c:0006 p:---- s:0021 e:000020 CFUNC :to_s
| c:0005 p:---- s:0018 e:000017 CFUNC :inspect
| c:0004 p:0004 s:0014 e:000013 BLOCK -:8 [FINISH]
| c:0003 p:---- s:0010 e:000009 CFUNC :each_object
| c:0002 p:0073 s:0006 e:000005 EVAL -:7 [FINISH]
| c:0001 p:0000 s:0003 E:002060 (none) [FINISH]
|
| -- Ruby level backtrace information ----------------------------------------
| -:7:in `<main>'
| -:7:in `each_object'
| -:8:in `block in <main>'
| -:8:in `inspect'
| -:8:in `to_s'
|
| -- C level backtrace information -------------------------------------------
| C:\Windows\SYSTEM32\ntdll.dll(NtWaitForSingleObject+0x14) [0x00007ffbdb40ef74]
| C:\Windows\System32\KERNELBASE.dll(WaitForSingleObjectEx+0x8e) [0x00007ffbd89fe7ae]
| x64-ucrt-ruby320.dll(rb_vm_bugreport+0x313) [0x00007ffba62417c3]
| x64-ucrt-ruby320.dll(rb_bug_without_die+0x75) [0x00007ffba6039d15]
| x64-ucrt-ruby320.dll(rb_bug+0x33) [0x00007ffba626e014]
| x64-ucrt-ruby320.dll(rb_out_of_int+0x42) [0x00007ffba626f81b]
| x64-ucrt-ruby320.dll(rb_vm_invoke_proc+0x22c) [0x00007ffba622c34c]
| x64-ucrt-ruby320.dll(rb_eval_cmd_kw+0x5ea) [0x00007ffba6230e7a]
| x64-ucrt-ruby320.dll(rb_funcallv+0x11) [0x00007ffba62310c1]
| x64-ucrt-ruby320.dll(rb_inspect+0x17) [0x00007ffba60f9417]
| x64-ucrt-ruby320.dll(rb_hash_values+0xfc1) [0x00007ffba606e791]
| x64-ucrt-ruby320.dll(rb_hash_values+0x102c) [0x00007ffba606e7fc]
| x64-ucrt-ruby320.dll(rb_st_foreach_check+0x77) [0x00007ffba61a1637]
| x64-ucrt-ruby320.dll(rb_hash_set_default_proc+0x1e19) [0x00007ffba60724a9]
| x64-ucrt-ruby320.dll(rb_ensure+0x18f) [0x00007ffba60453af]
| x64-ucrt-ruby320.dll(rb_hash_set_default_proc+0x2272) [0x00007ffba6072902]
| x64-ucrt-ruby320.dll(rb_hash_aset+0x1d1f) [0x00007ffba6077c2f]
| x64-ucrt-ruby320.dll(rb_mutex_trylock+0x51c) [0x00007ffba61d864c]
| x64-ucrt-ruby320.dll(rb_exec_recursive+0x17) [0x00007ffba61e0217]
| x64-ucrt-ruby320.dll(rb_error_arity+0x26e) [0x00007ffba62182ee]
| x64-ucrt-ruby320.dll(rb_vm_call_with_refinements+0x47d) [0x00007ffba6233fed]
| x64-ucrt-ruby320.dll(rb_vm_exec+0x255) [0x00007ffba62252a5]
| x64-ucrt-ruby320.dll(rb_yield+0x1e8) [0x00007ffba622ac88]
| x64-ucrt-ruby320.dll(rb_obj_id+0x1c94) [0x00007ffba6057024]
| x64-ucrt-ruby320.dll(rb_size_mul_or_raise+0x154) [0x00007ffba605c464]
| x64-ucrt-ruby320.dll(rb_ensure+0x18f) [0x00007ffba60453af]
| x64-ucrt-ruby320.dll(rb_objspace_each_objects_without_setup+0x1ac) [0x00007ffba606562c]
| x64-ucrt-ruby320.dll(rb_error_arity+0x26e) [0x00007ffba62182ee]
| x64-ucrt-ruby320.dll(rb_vm_search_method_slowpath+0x723) [0x00007ffba621ce33]
| x64-ucrt-ruby320.dll(rb_vm_call_with_refinements+0x4e8) [0x00007ffba6234058]
| x64-ucrt-ruby320.dll(rb_vm_exec+0x255) [0x00007ffba62252a5]
| x64-ucrt-ruby320.dll(rb_call_end_proc+0x130) [0x00007ffba603e400]
| x64-ucrt-ruby320.dll(ruby_run_node+0xa5) [0x00007ffba6044145]
| [0x00007ff62fcc15a8]
| [0x00007ff62fcc13b1]
| [0x00007ff62fcc14e6]
| C:\Windows\System32\KERNEL32.DLL(BaseThreadInitThunk+0x10) [0x00007ffbd93c4ed0]
</code></pre> Ruby master - Misc #18587 (Open): What was the reason behind Ruby choosing SipHash for Hash?https://redmine.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 - Bug #18510 (Open): Unexpected waiting for console when starting ruby on windowshttps://redmine.ruby-lang.org/issues/185102022-01-23T14:53:12ZYO4 (Yoshinao Muramatsu)
<a name="ruby-version"></a>
<h1 >ruby version<a href="#ruby-version" class="wiki-anchor">¶</a></h1>
<p>C:\Ruby31-x64\bin>"c:\Ruby31-x64\bin\ruby.exe" -v<br>
ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [x64-mingw-ucrt]</p>
<p>older versions have same issue too.</p>
<a name="how-to-reproduce"></a>
<h1 >how to reproduce<a href="#how-to-reproduce" class="wiki-anchor">¶</a></h1>
<p>execute ruby.exe from cmd.exe command promput like concatenating the quoted path and file name notation</p>
<pre><code>C:\Ruby31-x64\bin>"c:\Ruby31-x64\bin\"ruby.exe -v
# => wait for console input unexpectedly
puts "This is Console Input"^Z
=> This is Console Input
# ruby terminated, version not appear
</code></pre>
<p>It seems to commandline separation issue.</p> Ruby master - Bug #18444 (Open): Trapped TSTP causes a locking deadlock in 3.0.3 onwardhttps://redmine.ruby-lang.org/issues/184442021-12-28T16:01:45Zwhy-el (Mohamed Wael Khobalatte)
<p>A curious case:</p>
<p><code>ruby -e 'Signal.trap("TSTP") { puts "Received a terminal stop signal, but i will sleep instead."; sleep 10 }; loop {puts 1}'</code></p>
<p>this fails with <code>deadlock; recursive locking (ThreadError)</code> when I send the SIGTSTP via my terminal. This is on Mac OS Monterey (M1). It only happens in 3.0.3 and onward (I tried 3.1.0-preview1 as well, fails there too), when I try 3.0.2, the signal is handled properly.</p> Ruby master - Feature #18376 (Open): Version comparison APIhttps://redmine.ruby-lang.org/issues/183762021-12-01T16:56:05Zvo.x (Vit Ondruch)v.ondruch@tiscali.cz
<p>Is there a chance to have version comparison API? For example if <code>Gem::Version</code> was extracted into <code>::Version</code>. This idea was triggered by this PR <a href="https://github.com/mperham/connection_pool/pull/157" class="external">1</a> and <a href="https://github.com/mperham/connection_pool/issues/158" class="external">2</a>, where the <code>Gem::Version</code> API is used for comparing Ruby versions. While RubyGems might be available everywhere, it does not look correct to introduce dependencies on RubyGems into libraries which could run without them just fine.</p> Ruby master - Feature #18369 (Open): users.detect(:name, "Dorian") as shorthand for users.detect ...https://redmine.ruby-lang.org/issues/183692021-11-30T12:40:09Zdorianmariefr (Dorian Marié)
<p>Hi,</p>
<p>I was thinking I often do things like <code>collection.detect { |item| item.attribute == value }</code> and a shorthand like <code>collection.detect(:attribute, value)</code> would be quite useful</p>
<p>What do you think?</p>
<p>And I know there is <code>collection.detect { _1.attribute == value }</code> but I try not to use <code>_1</code> and this syntax would be shorter and simpler</p>
<p>Could also apply to other methods like <code>all?</code> (<code>collection.all?(:attribute, value)</code>), and basically any Enumerable method <a href="https://rubydoc.info/stdlib/core/Enumerable" class="external">https://rubydoc.info/stdlib/core/Enumerable</a></p> Ruby master - Bug #18359 (Open): [Windows MinGW] warning Please include winsock2.h before windows.hhttps://redmine.ruby-lang.org/issues/183592021-11-23T17:05:03ZMSP-Greg (Greg L)
<p>Compile warning from <code>include/ruby/win32.h</code>? Appears with both MINGW64 & UCRT64 builds.</p>
<pre><code>In file included from D:/ruby-mingw/include/ruby-3.1.0/ruby/win32.h:41,
from D:/ruby-mingw/include/ruby-3.1.0/ruby/internal/dosish.h:38,
from D:/ruby-mingw/include/ruby-3.1.0/ruby/defines.h:78,
from D:/ruby-mingw/include/ruby-3.1.0/ruby/ruby.h:25,
from D:/ruby-mingw/include/ruby-3.1.0/ruby.h:38,
from ../../../../ext/nokogiri/nokogiri.h:68,
from ../../../../ext/nokogiri/gumbo.c:30:
C:/msys64/mingw64/x86_64-w64-mingw32/include/winsock2.h:15:2: warning: #warning Please include winsock2.h before windows.h [-Wcpp]
15 | #warning Please include winsock2.h before windows.h
| ^~~~~~~
</code></pre> Ruby master - Misc #18352 (Open): What is the Hash#grep expected?https://redmine.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 - Feature #18291 (Open): When use =~ with named group, if regex is on the right side,...https://redmine.ruby-lang.org/issues/182912021-11-05T15:12:55Zzw963 (Wei Zheng)
<p>Following code not work.</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="k">if</span> <span class="s2">"Billy Zheng"</span> <span class="o">=~</span> <span class="sr">/(?<first_name>\w+)\s+(?<last_name>\w+)/</span>
<span class="nb">p</span> <span class="n">first_name</span>
<span class="nb">p</span> <span class="n">last_name</span>
<span class="k">end</span>
<span class="c1"># NameError: undefined local variable or method `first_name' for main:Object</span>
</code></pre>
<p>But, if we switch left and right between =~</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="k">if</span> <span class="sr">/(?<first_name>\w+)\s+(?<last_name>\w+)/</span> <span class="o">=~</span> <span class="s2">"Billy Zheng"</span>
<span class="nb">p</span> <span class="n">first_name</span>
<span class="nb">p</span> <span class="n">last_name</span>
<span class="k">end</span>
<span class="c1"># => "Billy"</span>
<span class="c1"># =>"Zheng"</span>
</code></pre>
<p>I know ruby keep this same behavior since 1.9, but i am curious if we can improve this?</p>
<p>I consider this as a bug, because that not good, when i want to use this way, i have to<br>
take care must write regexp before =~</p>
<p>Thank you.</p> Ruby master - Bug #18132 (Open): TODO: fix ccan/list thread safetyhttps://redmine.ruby-lang.org/issues/181322021-08-25T07:19:47Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<p>This library does not consider multi-threading at all.<br>
Callers must consider it instead.<br>
AFAIK, VM list has a problem, and others may.</p> Ruby master - Bug #18013 (Open): Unexpected results when mxiing negated character classes and cas...https://redmine.ruby-lang.org/issues/180132021-06-29T08:55:22Zjirkamarsik (Jirka Marsik)
<pre><code>irb(main):001:0> /[^a-c]/i.match("A")
=> nil
irb(main):002:0> /[[^a-c]]/i.match("A")
=> #<MatchData "A">
</code></pre>
<p>The two regular expressions above match different strings, because the character classes denote different sets of characters. In order for <code>/[^a-c]/i</code> to produce correct results, Oniguruma provided a fix that can still be easily seen in the code as it is hidden behind an always-on preprocessor flag (<code>CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS</code>, <a href="https://github.com/ruby/ruby/blob/9eae8cdefba61e9e51feb30a4b98525593169666/regparse.c#L5528" class="external">https://github.com/ruby/ruby/blob/9eae8cdefba61e9e51feb30a4b98525593169666/regparse.c#L5528</a>). The idea of the fix is to first case-fold a character class and only then apply the negation (essentially moving the case-fold operator <em>inside</em> the negation).</p>
<p>In the case of our first regular expression, <code>[a-c]</code> is case-folded into <code>[a-cA-C]</code> and that is then inverted into <code>[^a-cA-C]</code>, which is the expected result. However, this case-folding logic is currently only being applied to the top-most character class and so if we use a nested negated character class, the order of the operations will be switched.</p>
<p>With our second regular expression, <code>[a-c]</code> will first be negated to yield <code>[^a-c]</code>, which will then be case-folded into <code>.</code>, the set of all characters (since <code>[^a-c]</code> contains <code>A-C</code>, which case-fold into <code>a-c</code>).</p>
<p>A way to fix this would be to apply case-folding for nested character classes as well, so that the nested character classes behave the same as the top-most character class. Then, we would get the same semantics for both expressions.</p> Ruby master - Feature #17950 (Open): Unable to pattern-match against a String keyhttps://redmine.ruby-lang.org/issues/179502021-06-12T15:36:53Zchucke (Tiago Cardoso)
<p>I'm unable to parse against an internal hash, when the internal hash contains strings as keys:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">case</span> <span class="p">{</span><span class="ss">status: </span><span class="mi">200</span><span class="p">,</span> <span class="ss">headers: </span><span class="p">{</span><span class="s2">"content-type"</span> <span class="o">=></span> <span class="s2">"application/json"</span><span class="p">},</span> <span class="ss">body: </span><span class="s2">"bla"</span><span class="p">}</span>
<span class="k">in</span> <span class="p">{</span> <span class="ss">status: </span><span class="p">,</span> <span class="ss">headers: </span><span class="p">{</span><span class="s2">"content-type"</span> <span class="o">=></span> <span class="n">type</span><span class="p">},</span> <span class="ss">body: </span><span class="p">}</span>
<span class="c1"># syntax error, unexpected terminator, expecting literal content or tSTRING_DBEG or tSTRING_DVAR or tLABEL_END</span>
<span class="c1"># ...tus: , headers: {"content-type" => type}, body: }</span>
</code></pre>
<p>however, this works:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">h</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"content-type"</span> <span class="o">=></span> <span class="s2">"application/json"</span><span class="p">}</span>
<span class="k">case</span> <span class="p">{</span><span class="ss">status: </span><span class="mi">200</span><span class="p">,</span> <span class="ss">headers: </span><span class="p">{</span><span class="s2">"content-type"</span> <span class="o">=></span> <span class="s2">"application/json"</span><span class="p">},</span> <span class="ss">body: </span><span class="s2">"bla"</span><span class="p">}</span>
<span class="k">in</span> <span class="p">{</span> <span class="ss">status: </span><span class="p">,</span> <span class="ss">headers: </span><span class="o">^</span><span class="n">h</span><span class="p">,</span> <span class="ss">body: </span><span class="p">}</span>
</code></pre> Ruby master - Feature #17825 (Open): Uniformize Float::INFINITY and Date::infinity.newhttps://redmine.ruby-lang.org/issues/178252021-04-25T11:05:32ZAoernis (lucas billaudot)
<p>With <code>Float</code> you can do</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Float</span><span class="o">::</span><span class="no">INFINITY</span> <span class="c1"># Infinity</span>
</code></pre>
<p>and with <code>Date</code> you can do</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Date</span><span class="o">::</span><span class="no">Infinity</span><span class="p">.</span><span class="nf">new</span> <span class="c1"># #<Date::Infinity:0x00007f8d46a59ee0 @d=1></span>
</code></pre>
<p>but not</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Date</span><span class="o">::</span><span class="no">INFINITY</span> <span class="c1"># uninitialized constant Date::INFINITY</span>
</code></pre>
<a name="Background"></a>
<h4 >Background<a href="#Background" class="wiki-anchor">¶</a></h4>
<p><code>Date::Infinity.new</code> and <code>Float::INFINITY</code> have both the same ancestors and have same using purpose<br>
So it feel odd no be able to call them the same way</p>
<a name="Proposal"></a>
<h4 >Proposal<a href="#Proposal" class="wiki-anchor">¶</a></h4>
<p>Just make <code>Date::INFINITY</code> a working thing<br>
And maybe mark <code>Date::Infinity.new</code> as deprecated ¯_(ツ)_/¯</p>
<p>Thanks for reading</p> Ruby master - Feature #17566 (Open): Tune thread QoS / efficiency on macOShttps://redmine.ruby-lang.org/issues/175662021-01-20T20:25:26Zmperham (Mike Perham)mperham@gmail.com
<p>Hi, new Apple M1 processors have "performance" and "efficiency" cores. Apple provides a QoS API so threads can tune which cores they should execute on. Some threads should be executed as high-priority, some should be treated as low-priority.</p>
<p>This page shows the pthread APIs that Apple provides:</p>
<p><a href="https://developer.apple.com/library/archive/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/PrioritizeWorkAtTheTaskLevel.html" class="external">https://developer.apple.com/library/archive/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/PrioritizeWorkAtTheTaskLevel.html</a></p>
<pre><code>pthread_set_qos_class_self_np(QOS_CLASS_BACKGROUND, 0)
</code></pre>
<p>I noticed Ruby already provides <code>Thread#priority=</code> which says <code>This is just hint for Ruby thread scheduler. It may be ignored on some platform</code>. Does this API work still or was it only active for Ruby 1.8's green threads? Should this API use the QoS APIs on macOS?</p> Ruby master - Feature #17562 (Open): Update -E option in --helphttps://redmine.ruby-lang.org/issues/175622021-01-19T16:42:45Zima1zumi (Mari Imaizumi)
<p>I would like to propose explaining the arguments of the -E option specifically in --help.</p>
<p>The current explanation is a bit difficult for beginners to understand.<br>
I tried to change <code>Encoding.default_internal</code>, but I changed <code>Encoding.default_external</code> by mistake. That confused me because I didn't know how to use it. Therefore, I have updated the explanation.</p>
<p>before:</p>
<pre><code> -Eex[:in], --encoding=ex[:in]
specify the default external and internal character encodings
</code></pre>
<p>after:</p>
<pre><code> -Eexternal-encoding[:internal-encoding], --encoding=external-encoding[:internal-encoding]
specify the default external and internal character encodings
</code></pre>
<p>diff:</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/ruby.c b/ruby.c
index 5bac96b5e1..4f8975a399 100644
</span><span class="gd">--- a/ruby.c
</span><span class="gi">+++ b/ruby.c
</span><span class="p">@@ -281,7 +281,7 @@</span> usage(const char *name, int help, int highlight, int columns)
M("-Cdirectory", "", "cd to directory before executing your script"),
M("-d", ", --debug", "set debugging flags (set $DEBUG to true)"),
M("-e 'command'", "", "one line of script. Several -e's allowed. Omit [programfile]"),
<span class="gd">- M("-Eex[:in]", ", --encoding=ex[:in]", "specify the default external and internal character encodings"),
</span><span class="gi">+ M("-Eexternal-encoding[:internal-encoding]",", --encoding=external-encoding[:internal-encoding]","specify the default external and internal character encodings"),
</span> M("-Fpattern", "", "split() pattern for autosplit (-a)"),
M("-i[extension]", "", "edit ARGV files in place (make backup if extension supplied)"),
M("-Idirectory", "", "specify $LOAD_PATH directory (may be used more than once)"),
</code></pre>
<p>PR: <a href="https://github.com/ruby/ruby/pull/4099" class="external">https://github.com/ruby/ruby/pull/4099</a></p> Ruby master - Feature #17550 (Open): Why no function to get all subdirectories of a directory?https://redmine.ruby-lang.org/issues/175502021-01-17T20:59:19Zasfarley (Alexander Farley)
<p>Googling around, this seems to be a relatively common request. Would you be willing to accept a pull request implementing this feature?</p> Ruby master - Misc #17309 (Open): URI.escape being deprecated, yet there is no replacementhttps://redmine.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 - Feature #16971 (Open): weak_ref&.some_method should behave like object&.some_methodhttps://redmine.ruby-lang.org/issues/169712020-06-19T15:07:55Zkwerle (Kurt Werle)kurt@CircleW.org
<p>The following patterns mean basically the same thing and should behave the same:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">weak_ref</span> <span class="o">=</span> <span class="no">WeakRef</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">some_object</span><span class="p">)</span>
<span class="o">...</span>
<span class="n">weak_ref</span><span class="p">.</span><span class="nf">some_method</span> <span class="k">if</span> <span class="n">weak_ref</span><span class="p">.</span><span class="nf">weakref_alive?</span><span class="p">()</span>
<span class="n">some_object</span><span class="p">.</span><span class="nf">some_method</span> <span class="k">if</span> <span class="n">some_object</span><span class="p">.</span><span class="nf">present?</span>
</code></pre>
<p>The some_object predicate got cleaned up by using &.some_method. It would be super clean if WeakRef did the same.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">weak_ref</span> <span class="o">=</span> <span class="no">WeakRef</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">some_object</span><span class="p">)</span>
<span class="o">...</span>
<span class="n">weak_ref</span><span class="o">&</span><span class="p">.</span><span class="nf">some_method</span> <span class="c1"># should not raise WeakRef::RefError</span>
</code></pre> Ruby master - Feature #16755 (Open): warning: `if' at the end of line without an expressionhttps://redmine.ruby-lang.org/issues/167552020-04-03T14:47:11Zmpapis (Michal Papis)mpapis@gmail.com
<p>I'm using this notation in a lot of scripts:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">if</span>
<span class="kp">true</span>
<span class="k">then</span>
<span class="nb">puts</span> <span class="ss">:a</span>
<span class="k">else</span>
<span class="nb">puts</span> <span class="ss">:b</span>
<span class="k">end</span>
</code></pre>
<p>Using ruby 2.6.5 I'm getting expected response:</p>
<pre><code class="shell syntaxhl" data-language="shell"><span class="o">(</span>0<span class="o">)</span> 2.6.5 mpapis@mpapis-linux:~/tmp>ruby <span class="nt">-w</span> test.rb
a
</code></pre>
<p>Using ruby 2.7.1 I'm getting extra warning:</p>
<pre><code class="shell syntaxhl" data-language="shell"><span class="o">(</span>0<span class="o">)</span> 2.7.1 mpapis@mpapis-linux:~/tmp>ruby <span class="nt">-w</span> test.rb
test.rb:1: warning: <span class="sb">`</span><span class="k">if</span><span class="s1">' at the end of line without an expression
a
</span></code></pre>
<p>I've tracked it to the following git commits:</p>
<ul>
<li>ba35c14325ebbf1da8f200df83c45ee9937ff8a1</li>
<li>c303854e134043d905baff2385add44cc2c28756</li>
<li>26316cc350109ba71d42f944f3b976985627c042</li>
<li>e91e3274bebc803b97971ad0a6f4ee3a8c646a60</li>
<li>a087e027bf7cf0fbb825f1d55668f85ab1f3c9e6</li>
<li>30a74aaef00a99364f5423439ac44babf5066dc0</li>
</ul> Ruby master - Feature #16684 (Open): Use the word "to" instead of "from" in backtracehttps://redmine.ruby-lang.org/issues/166842020-03-10T16:00:53Zsawa (Tsuyoshi Sawada)
<p>The most-recent-call-last order of backtrace introduced by <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Add option to print backtrace in reverse order (stack frames first and error last) (Closed)" href="https://redmine.ruby-lang.org/issues/8661">#8661</a>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">a</span><span class="p">;</span> <span class="k">raise</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">b</span><span class="p">;</span> <span class="n">a</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">c</span><span class="p">;</span> <span class="n">b</span> <span class="k">end</span>
<span class="n">c</span>
</code></pre>
<p><strong>Current</strong></p>
<pre><code>Traceback (most recent call last):
3: from foo.rb:4:in `<main>'
2: from foo.rb:3:in `c'
1: from foo.rb:2:in `b'
foo.rb:1:in `a': unhandled exception
</code></pre>
<p>is intuitive to me, and I hope it is retained. However, there are people complaining that it is confusing. I believe the unnaturalness is (at least partly) due to the fact that the word "from" is used, which made sense when backtrace was displayed in most-recent-call-first order,</p>
<pre><code>foo.rb:1:in `a': unhandled exception
1: from foo.rb:2:in `b'
2: from foo.rb:3:in `c'
3: from foo.rb:4:in `<main>'
</code></pre>
<p>but not any more. Here, my understanding is that "from" means that the previous line was called <strong>from</strong> that line.</p>
<p>I propose that, so long as the most-recent-call-last order is adopted, the word "to" should be used rather than "from", which would mean that the previous line leads <strong>to</strong> that line:</p>
<p><strong>Proposed 1</strong></p>
<pre><code>Traceback (most recent call last):
3: to foo.rb:4:in `<main>'
2: to foo.rb:3:in `c'
1: to foo.rb:2:in `b'
foo.rb:1:in `a': unhandled exception
</code></pre>
<p>Or, as an alternative, if it looks unnatural to have "to" in the first line, and to lack one before the message line, we may put it at the end of a line:</p>
<p><strong>Proposed 2</strong></p>
<pre><code>Traceback (most recent call last)
3: foo.rb:4:in `<main>' to:
2: foo.rb:3:in `c' to:
1: foo.rb:2:in `b' to:
foo.rb:1:in `a': unhandled exception
</code></pre>
<p>By using different words, it would become easier to understand the display order at a glance, and even by just looking at a single line.</p> Ruby master - Feature #16673 (Open): total_timeout for Net::HTTPhttps://redmine.ruby-lang.org/issues/166732020-03-05T00:16:59Zmohamedhafez (Mohamed Hafez)
<p><code>Net::HTTP</code> allows setting <code>open_timeout</code> and <code>read_timeout</code>, but sometimes I just want to make sure an API call will finish within a set amount of time, and am not concerned with how long opening the connection takes and reading the connection takes individually, as long as the total is beneath a certain amount. Yes, one could set <code>open_timeout</code> + <code>read_timeout</code> to be equal to the maximum time they are willing to wait, but then for example if opening the socket happens almost immediately, I may get a read timeout when I am still willing to wait a bit longer (this is the case for the service I run, where we hit an external API that occasionally takes 60s to respond, and am trying to catch some of those longer running requests. it also occasionally takes over 5 seconds to open a connection, so I can't make open_timeout minimal either). In other languages, setting a total timeout is possible, like for example Java's <code>HttpRequest</code>.</p>
<p>My intern <a class="user active user-mention" href="https://redmine.ruby-lang.org/users/35721">@LevonAr (Levon Arabyan )</a> is willing to work on this, and put in a <code>total_timeout</code> option in a way that doesn't interfere with the current functioning of open_timeout and read_timeout. Would a patch to put in this feature be accepted?</p> Ruby master - Feature #16637 (Open): Time#to_s and Date#to_s accept strftime format stringhttps://redmine.ruby-lang.org/issues/166372020-02-17T15:14:05Zttilberg (Tim Tilberg)
<p>While terms like <code>strftime</code> and <code>strptime</code> are ubiqutous through the history of computer science, I feel that the terms are very dense. If you are not already in-the-know, they are gibberish. If you are in the know, they are still a bit clunky. While discussing ways to improve the Time and Date formatting APIs for humanity, I thought a quick and easy improvement would be removing the need to use the method <code>#strftime</code>. <code>#format</code> is already reserved as a private method, but how do people feel about allowing a format string as an argument for <code>#to_s</code>?</p>
<p>I'm not comfortable writing C, but the relevant code is <a href="https://github.com/ruby/ruby/blob/dcb05179a969a024bbd3b7622f67468ddf07638c/time.c#L4097" class="external">here</a></p>
<p>It seems like it would be straightforward to use the current strings as default values, but to allow for a format string to be passed in.</p>
<pre><code>time_to_s(VALUE time) // add format arg
{
struct time_object *tobj;
GetTimeval(time, tobj);
if (TZMODE_UTC_P(tobj))
return strftimev("%Y-%m-%d %H:%M:%S UTC", time, rb_usascii_encoding()); // format || "%Y-%m-%d %H:%M:%S UTC"
else
return strftimev("%Y-%m-%d %H:%M:%S %z", time, rb_usascii_encoding()); // format || "%Y-%m-%d %H:%M:%S %z"
}
</code></pre>
<p>This would allow an API that feels a bit more intuitive. You still have to know the formatting symbols, but it creates a much more expressive statement:</p>
<pre><code># The current time, to string. What kind of string? A Y-m-d string.
Time.now.to_s('%Y-%m-%d')
</code></pre>
<p>(As an aside for discussion, I feel this way about formatting things like Floats and other numbers also. That API is equally confusing, and a holdover from history in comp-sci.)</p> Ruby master - Misc #16507 (Open): =~ vs include? or match?https://redmine.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 - Feature #16471 (Open): Two feature requests for WeakRef: get original object, callb...https://redmine.ruby-lang.org/issues/164712020-01-01T19:16:52ZSnappingturtle (Mike O'Sullivan)
<p>I'd like to request two features for <code>WeakRef</code>. I'll explain what I want, then provide a real world use case.</p>
<p>First, add the ability to pull the original object out of the <code>WeakRef</code> object, something like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">myhash</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">myhash</span> <span class="o">=</span> <span class="no">WeakRef</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">myhash</span><span class="p">)</span>
<span class="n">myhash</span> <span class="o">=</span> <span class="n">myhash</span><span class="p">.</span><span class="nf">original_object</span><span class="p">()</span>
</code></pre>
<p>Second, add a callback feature for when a WeakRef's object is being purged by GC. It would work something like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">wr</span> <span class="o">=</span> <span class="no">WeakRef</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">myobject</span><span class="p">)</span>
<span class="n">wr</span><span class="p">.</span><span class="nf">on_garbage</span><span class="p">()</span> <span class="k">do</span> <span class="o">|</span><span class="n">wr</span><span class="o">|</span>
<span class="nb">puts</span> <span class="s1">'trashing'</span>
<span class="k">end</span>
<span class="c1"># time goes by...</span>
<span class="c1"># myobject goes out of scope</span>
<span class="c1"># outputs "trashing"</span>
</code></pre>
<p>Here's the specific use case I would want it for. I'm developing a database system which includes a class called <code>Node</code>. A <code>Node</code> object holds a reference to a database handle and the primary key of a record in that database. It also has methods for getting and setting values in that record. So a simplified version looks something like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Node</span>
<span class="nb">attr_reader</span> <span class="ss">:dbh</span>
<span class="nb">attr_reader</span> <span class="ss">:pk</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">dbh</span><span class="p">,</span> <span class="n">pk</span><span class="p">)</span>
<span class="vi">@dbh</span> <span class="o">=</span> <span class="n">dbh</span>
<span class="vi">@pk</span> <span class="o">=</span> <span class="n">pk</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">set</span><span class="p">(</span><span class="n">fieldname</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
<span class="c1"># a bunch of SQL to set the value</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="n">fieldname</span><span class="p">)</span>
<span class="c1"># a bunch of SQL to get the value</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">node</span> <span class="o">=</span> <span class="no">Node</span><span class="p">.</span><span class="nf">new</span> <span class="n">dbh</span><span class="p">,</span> <span class="s1">'abc'</span>
<span class="n">node</span><span class="p">.</span><span class="nf">set</span> <span class="s1">'name'</span><span class="p">,</span> <span class="s1">'Fred'</span>
</code></pre>
<p>The database object will have a node method, so you would usually get nodes like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">node</span> <span class="o">=</span> <span class="n">dbh</span><span class="p">.</span><span class="nf">node</span><span class="p">(</span><span class="s1">'abc'</span><span class="p">)</span>
</code></pre>
<p>Make sense so far? It's a pretty simple concept. It works, but I'd like to make a small improvement. (Whether or not it's actually an improvement is a judgement call... I expect some disagreement on this point. But work with me here.)</p>
<p>I'd like the database object to keep a cache of <code>Node</code> objects. However, the database doesn't keep those node objects alive: they can fall out of scope and get purged by the GC. However, if that cache is never purged of dead objects, it just grows bigger and bigger. I could occasionally just run a routine to work through the cache and purge dead references, but that seems very inefficient. It would be better to just have them purged as they die.</p>
<p>So I could implement it something like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">DataBase</span>
<span class="nb">attr_reader</span> <span class="ss">:cache</span>
<span class="k">def</span> <span class="nf">initialize</span>
<span class="vi">@cache</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">node</span><span class="p">(</span><span class="n">pk</span><span class="p">)</span>
<span class="k">if</span> <span class="vi">@cache</span><span class="p">[</span><span class="n">pk</span><span class="p">]</span>
<span class="c1"># Here's where we need to get at the original object</span>
<span class="k">return</span> <span class="vi">@cache</span><span class="p">[</span><span class="n">pk</span><span class="p">].</span><span class="nf">original_object</span>
<span class="k">else</span>
<span class="n">new_node</span> <span class="o">=</span> <span class="no">Node</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="n">pk</span><span class="p">)</span>
<span class="vi">@cache</span><span class="p">[</span><span class="n">pk</span><span class="p">]</span> <span class="o">=</span> <span class="no">WeakRef</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">new_node</span><span class="p">)</span>
<span class="c1"># Here's where we set the callback</span>
<span class="vi">@cache</span><span class="p">[</span><span class="n">pk</span><span class="p">].</span><span class="nf">on_garbage</span> <span class="k">do</span> <span class="o">|</span><span class="n">wr</span><span class="o">|</span>
<span class="n">wr</span><span class="p">.</span><span class="nf">db</span><span class="p">.</span><span class="nf">cache</span><span class="p">.</span><span class="nf">delete</span> <span class="n">wr</span><span class="p">.</span><span class="nf">pk</span>
<span class="k">end</span>
<span class="k">return</span> <span class="n">new_node</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>So when a <code>Node</code> object is garbage collected, it's deleted from the cache. The cache stays clean of dead objects.</p>
<p>I'll be interested to hear what you think of this idea and how difficult it would be to implement it.</p> Ruby master - Misc #16396 (Open): What is the reason for this behaviour of Find.find?https://redmine.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 #16157 (Open): What is the correct and *portable* way to do generic delegation?https://redmine.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 - Feature #16128 (Open): Would it be possible for ruby to warn about case/when menu o...https://redmine.ruby-lang.org/issues/161282019-08-25T15:52:14Zshevegen (Robert A. Heiler)shevegen@gmail.com
<p>I was not sure whether the following behaviour is a bug or not, so I filed this under "feature", mostly because<br>
this may change existing behaviour; and even if I think the current behaviour in this context may not make a<br>
lot of sense, perhaps there are caveats; or it may be too insignificant to want to change.</p>
<p>Anyway, without further ado, I will next show the ruby code that can be used to reproduce the issue/behaviour<br>
that I refer to:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Foo</span>
<span class="k">def</span> <span class="nf">initialize</span>
<span class="n">menu</span><span class="p">(</span><span class="ss">:random_colour</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">menu</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="k">case</span> <span class="n">i</span><span class="p">.</span><span class="nf">to_s</span>
<span class="k">when</span> <span class="sr">/^-?-?random(-|_)?colou?r$/i</span><span class="p">,</span>
<span class="sr">/rcolour$/i</span><span class="p">,</span>
<span class="s1">'RCOL'</span><span class="p">,</span>
<span class="n">print_foobar</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">print_foobar</span>
<span class="nb">print</span> <span class="s1">'foobar'</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Foo</span><span class="p">.</span><span class="nf">new</span>
</code></pre>
<p>To those who may not immediately see the problem - it is the last ',' character<br>
in the case/when menu, right after the string 'RCOL'.</p>
<p>The above snippet was part of a much larger class/codebase, so I narrowed it<br>
down to this smaller example.</p>
<p>If you run this code, you will see no output. The reason is due to the ','.</p>
<p>If you remove the ',', then you get the desired output - the invocation of<br>
the method called print_foobar() which will print 'foobar'.</p>
<p>I discovered this strange behaviour by accident in a much larger case/when<br>
menu (my case/when menu interfaces can be excessively long, I admit this).</p>
<p>Sometimes I re-arrange the case menu, and then I may forget the ',' there,<br>
so I paste the ',' with the line, which sometimes leads to above situation,<br>
which tends to confuse me. I am quite used to this at this point, so<br>
discovering the problem does not take me long - but I was wondering whether<br>
this current behaviour is useful for anything?</p>
<p>Because if not then perhaps there could be a warning by ruby, possibly by<br>
the did-you-mean gem, or by ruby directly even without the did-you-mean<br>
gem (although I think this may fit the did-you-mean gem). I have, however<br>
had, decided to first report this to ruby core anyway, because perhaps I<br>
am missing something obvious that may explain the behaviour. Or perhaps it<br>
is difficult to distuingish what the next lines should be. But I assume<br>
that the ruby parser assumes another case/when statement here, after the<br>
',', so does not treat the above as an error or problematic behaviour.</p>
<p>Perhaps the above can still be reported based on additional information,<br>
such as correct indent level? I indent uniformly and consistently, so<br>
the above could provide additional cues what the ruby user at hand may<br>
have wanted to see - as in the example above, I don't think the trailing<br>
',' is useful; it was just a typo. I am not sure how easy it is to distinguish<br>
this case between cases where the user wanted to have a ','.</p>
<p>I am not sure how easy it would be to change the behaviour of ruby in<br>
this regard, or if it is wanted, or if it takes too much time, but I thought<br>
it is better to report it anyway - others can give their opinion in this<br>
case. Thanks!</p> Ruby master - Feature #15817 (Open): Warnings for undef_method and remove_method on initialize()https://redmine.ruby-lang.org/issues/158172019-05-02T09:11:49Zshevegen (Robert A. Heiler)shevegen@gmail.com
<p>Title: Warnings for undef_method and remove_method on initialize()</p>
<p>Right now ruby warns you if you remove or undefine initialize, at the least if you<br>
run in verbose mode e. g. the -w flag.</p>
<p>Example for such a warning:</p>
<pre><code>gtk_combo_box.rb:17: warning: undefining `initialize' may cause serious problems
</code></pre>
<p>What am I trying to do here, that caused this warning to appear, actually?</p>
<p>I am modifying some of the ruby-gtk code to extend the core gtk widgets with some<br>
"shortcuts", that is, functionality that I may use in order to write less code when<br>
I write ruby-gtk specific code.</p>
<p>Part of this means that I have to modify how initialize works for some of these<br>
widgets; in particular enabling support for some Symbols via blocks given to the<br>
initializer (I happily use/abuse Symbols that way; ruby-gtk has also added a few<br>
Symbols in the last few years, in particular to avoid having to type long CONSTANT<br>
names when it is not necessary - see Kouhei Sutou's continued efforts here).</p>
<p>In order to do this, and modify these gtk-widgets, I thus modify initialize - and<br>
ruby gives me warnings here.</p>
<p>The first warning I actually got was:</p>
<p>"warning: method redefined; discarding old initialize"</p>
<p>Ok, fair enough. So my idea was ... "I'll simply remove the old initialize, and<br>
then set a new one, aka my own variant. That way I won't get the warning anymore."</p>
<p>I then tried to use both remove_method, and undef_method, and while initialize is<br>
removed, ruby still warns me, e. g. with the "may cause serious problems" issue.<br>
This was the reason (and moment) for creating the issue request here.</p>
<p>I should say that I always run all my ruby code with warning flags enabled, set in<br>
the shebang-header in a .rb file. I find it very useful that ruby tells me if<br>
there may be something wrong in general. However had, in this particular case, I<br>
actually consider ruby warning me to be a feature that I would prefer to not have,<br>
in that particular instance. The reason is that I am actually specifically telling<br>
ruby to get rid of the old initialize, so it is a bit surprising to me that ruby<br>
warns me. Here the assumption may be that the ruby user did not know what was done,<br>
and although I am still quite clueless, I actually think that in this case I knew<br>
what I wanted to do - that is, getting rid of the old initialize, then setting a<br>
new initialize. (Perhaps ruby could detect such a case, where the ruby users removes<br>
the old initialize, then specifically defines a new one; this may solve the issue<br>
here, but I have no idea how feasible this may be, or how much work. Just mentioning<br>
it really.)</p>
<p>We can say that my approach is not a good one; this may well be, but the primary question<br>
is whether ruby should warn/notify us in such a case either way.</p>
<p>I think you can find arguments for both cases, e. g. that ruby warns us (some people may<br>
want this, even in this case) when it comes to undef_method/remove_method on initialize<br>
only - but it may also equally be the case that the ruby user at hands knows what she/he/it<br>
is doing. And I believe that in the latter case ruby should NOT warn about this. Obviously<br>
ruby then would need a way to distinguish between these two cases:</p>
<p>a) the case where the user wants to see a warning, because it may be helpful or for any other reason<br>
b) the case where the user does not want to see the warning, for whatever reason</p>
<p>This makes the issue request here a bit complicated, because while I actually think that<br>
ruby should not warn in regards to undef_method/remove_method, there are also perfectly<br>
valid use cases for the latter, where ruby should warn. One use case can be when people<br>
dynamically add/remove methods and may "accidentally" - and automatically - remove initialize,<br>
so in this case it would be a GOOD thing that ruby warns them. But in other cases, such as in<br>
the use case described here, I would rather prefer to not have ruby print anything about this<br>
to me.</p>
<p>There are workarounds of course - for example, I can temporarily silence on $VERBOSE, and then<br>
re-set it to the old value. I do this in other gems.</p>
<p>There may be other workarounds - perhaps working on a new copy of initialize and then replacing<br>
the old one differently (not sure if these work ... perhaps with some variant of the *eval-family).<br>
All of which is fine - my primary reason here is that I believe it should be simple for the<br>
ruby user to tell ruby to not warn about a specific error at hand, e. g. in all the cases where<br>
the user knows the problem domain (and thus does not need the warning at hand).</p>
<p>I have no really good general suggestion in how to improve this aspect here, because it may be<br>
better to make warnings in ruby more flexible in general. Perhaps even on a per module/class<br>
"namespace" - a bit similar to refinements, but with a simple(r) API and a simple(r) concept.</p>
<p>I don't have a good proposal here either, so this is just a little bit of feedback really. (If<br>
there are more similar comments about warnings in ruby in general, please feel free to close<br>
the issue here and gather discussions in any other tracker issue if you feel this to be better.)</p>
<p>To further explain the above issue - my use case was primarily motivated in order to silence the<br>
first warning. It took me a little bit by surprise that my course of action then led to another<br>
warning, which sort of defeated my original intent of silencing the other warning, since I now<br>
had a new warning issued on the commandline. :)</p>
<p>Hopefully I could describe the intent/idea behind the suggestion. It is of course nothing that<br>
is hugely important, since it is just a warning and the code works fine, but I kind of like<br>
seeing no warnings on the commandline actually (don't know why but I dislike seeing warnings<br>
when I can avoid them).</p>
<p>PS: I think for the particular issue at hand, I will do the old trick with temporarily modifying<br>
$VERBOSE. It feels a bit hackish, but it also kind of works, and I can then silence the specific<br>
warning at hand, e. g. "wrap" the offending code part between $VERBOSE or two method calls that<br>
modify $VERBOSE; so perhaps a more general solution may be to be able to modify $VERBOSE through<br>
method calls in general, though I don't know if this would make the code too slow, or where this<br>
method should reside (Kernel? Not sure) - I just think it may be nicer to read, API-wise, to have<br>
a method rather than have to modify $VERBOSE. But that is just an opinion really; the more<br>
important thing is that modifying $VERBOSE does work, so the functionality already exists<br>
for us to use as-is.</p> Ruby master - Feature #15781 (Open): Unify Method List Introspection?https://redmine.ruby-lang.org/issues/157812019-04-21T20:43:58Zrbjl (Jan Lelis)hi@ruby.consulting
<p>Although Ruby has many core methods for retrieving the list of methods available to an object, or to the instances of a class, I believe they have gotten a little confusing (<a href="https://idiosyncratic-ruby.com/25-meta-methodology.html" class="external">also see</a>):</p>
<ul>
<li>
<code>Object#methods</code> and <code>Module#instance_methods</code> do not include <strong>private</strong> methods (at the same time they do include <strong>protected</strong> ones). There is already <code>Object#public_methods</code> (and <code>Object#protected_methods</code>) for distinguishing visibility scope , but no way to get <em>all</em> methods of an object.</li>
<li>There is the inconsistency that in most cases the argument being passed to <code>*_methods</code> methods let's you decide if you want to consider the inheritance chain, or not - But the prominent exception is <code>Object#methods</code> which instead toggles inheritance to singleton only! (for which we also have <code>Object#singleton_methods</code>)</li>
<li>There is no direct API for getting a list of private singleton methods</li>
</ul>
<p>Now that we have keyword arguments, we could provide a single API for listing methods. One way of doing so could be the <a href="https://github.com/janlelis/object_shadow#method-introspection" class="external">Object#shadow's methods method</a>. Having a keyword arguments based API would allow users to specify the dimensions of their requests better - should it:</p>
<ul>
<li>return the object's methods, or methods of its instances?</li>
<li>return only methods of a specific visibility scope?</li>
<li>return only methods of a specific inheritance level (e.g. only singleton, or all the way down to <code>BasicObject</code>)?</li>
</ul>
<p>What do you think about having one unified way for retrieving an object's method list?</p> Ruby master - Misc #15568 (Open): TracePoint(:raise)#parameters raises RuntimeErrorhttps://redmine.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 - Feature #15438 (Open): Threads can't switch faster than TIME_QUANTUM_(NSEC|USEC|MSEC)https://redmine.ruby-lang.org/issues/154382018-12-19T23:40:45Zsylvain.joyeux (Sylvain Joyeux)
<p>Thread#priority can be set to negative values, which when looking at the code is meant to reduce the time allocated to the thread. However, as far as I could understand in the codebase, the quantum of time is definitely hard-coded to 100ms (TIME_QUANTUM_...). This means that the "lower allocated time" would only work for threads that would often yield one way or the other (sleep, blocking calls, ...)</p>
<p>My projects would definitely benefit from a faster switching period. I was wondering how best to implement this ability ?</p>
<p>I thought of the following:</p>
<ol>
<li>globally using an environment variable</li>
<li>globally using an API</li>
<li>trying to adapt dynamically, using the highest needed period</li>
<li>lowering the period when a priority lower than 0 is set, leaving it at the lower period.</li>
</ol>
<p>Obviously (3) would seem to be the best, but I'm not sure I would be able to get it right in a decent amount of time. (4) seem to be a good trade-off between simplicity and performance (nothing changes if you never use priorities lower than 0, and if you were you basically get what you wanted).</p>
<p>What do you think ?</p> Ruby master - Feature #15413 (Open): unmarkable C stack (3rd stack)https://redmine.ruby-lang.org/issues/154132018-12-14T21:32:15Znormalperson (Eric Wong)normalperson@yhbt.net
<p>The current machine (C) stack can get pretty big for some C functions<br>
(rb_ensure, rb_f_select/rb_thread_fd_select/...). This is harmful when we stop<br>
a fiber/thread and all that stack becomes eligible for marking.</p>
<p>We should experiment a bump allocator for temporary allocations which<br>
behaves like the stack, but does not get marked by GC. VALUEs will continue<br>
to be allocated on normal C stack, but non-VALUE stuff can go to the<br>
unmarkable machine stack.</p>
<p>Maybe we call it "UMMS" for Un-Markable Machine Stack</p>
<p>We cannot remove marking of the current C stack for compatibility;<br>
but we can transition existing C code to use UMMS.</p>
<p>I probably won't be around to work on it for 2.7, unfortunately.</p> Ruby master - Bug #15247 (Open): Windows - TEMP folder, non 8.3 & drive, fails & errors in test-a...https://redmine.ruby-lang.org/issues/152472018-10-23T17:02:28ZMSP-Greg (Greg L)
<p>While working with Azure pipelines, two issues came up related to the TEMP folder.</p>
<p>1. The standard Windows TEMP folder is located in a user directory. The user for pipeplines is 'buildguest', which is greater than 8 characters, and hence, its short and long paths differ. When I created a new user account locally on Windows 10, both ENV['TEMP'] and ENV['TMP'] were set to the short path.</p>
<p>This is causes two failures in <code>test/rdoc/test_rdoc_rdoc.rb</code> and one failure in <code>test_dir.rb</code>, the failures are listed in the attached file temp_short-long.txt.</p>
<p>2. Azure pipelines has the normal TEMP folder on drive C:, but, unlike Appveyor, the repo is placed on drive D:. This causes one failure in <code>test/rdoc/test_rdoc_options.rb</code>, and two errors from the same file, but in the std-Lib file <code>pathname.rb</code>. See attached file temp_drive.txt.</p>
<p>I'm not really sure what I think the solution for this is, as the issue is really due to Windows setting ENV['TEMP'] and ENV['TMP'] to short paths. I do recall the same issues happened on my old multi-drive desktop system. At the time, there were more significant issues with build/test, so I reconfigured the env for that...</p> Ruby master - Feature #15031 (Open): T_RANGE for testing whether object is a Rangehttps://redmine.ruby-lang.org/issues/150312018-08-27T05:28:28Zv0dro (Sameer Deshmukh)sameer.deshmukh93@gmail.com
<p>Range is an in-built type of Ruby and it would be better for C extension<br>
writers if there existed a constant <code>T_RANGE</code> that could be directly used<br>
for checking whether a <code>VALUE</code> is a <code>Range</code>.</p>
<p>Currently we need to write <code>CLASS_OF(obj) == rb_cRange</code> in order to make this<br>
happen. Having a <code>T_RANGE</code> would help in making C code more idiomatic and fast<br>
in some cases.</p>
<p>That way, one can write <code>RB_TYPE_P(obj, T_RANGE)</code>.</p> Ruby master - Misc #14825 (Open): When redefining `attr_xx` methods the visibility becomes `public` https://redmine.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 - Feature #14800 (Open): Zlib::GzipReader#read does not support 2nd argumenthttps://redmine.ruby-lang.org/issues/148002018-05-31T14:32:52Zokkez (okkez _)
<p><code>Zlib::GzipReader#read</code> does not support 2nd argument for output buffer.<br>
It is not same as <code>IO#read</code> and <code>StringIO#read</code>.</p>
<p>It is useful for duck typing to copy both plain files and gzipped files.</p>
<p>See also</p>
<ul>
<li><a href="https://docs.ruby-lang.org/en/2.5.0/Zlib/GzipReader.html#method-i-read" class="external">https://docs.ruby-lang.org/en/2.5.0/Zlib/GzipReader.html#method-i-read</a></li>
<li><a href="https://docs.ruby-lang.org/en/2.5.0/IO.html#method-i-read" class="external">https://docs.ruby-lang.org/en/2.5.0/IO.html#method-i-read</a></li>
<li><a href="https://docs.ruby-lang.org/en/2.5.0/StringIO.html#method-i-read" class="external">https://docs.ruby-lang.org/en/2.5.0/StringIO.html#method-i-read</a></li>
</ul> Ruby master - Misc #14735 (Open): thread-safe operations in a hash could be documentedhttps://redmine.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 - Feature #14723 (Open): [WIP] sleepy GChttps://redmine.ruby-lang.org/issues/147232018-04-29T03:57:07Znormalperson (Eric Wong)normalperson@yhbt.net
<p>The idea is to use "idle time" when process is otherwise sleeping<br>
and using no CPU time to perform GC. It makes sense because real<br>
world traffic sees idle time due to network latency and waiting<br>
for user input.</p>
<p>Right now, it's Linux-only. Future patches will affect other sleeping<br>
functions:</p>
<p>IO.select, Kernel#sleep, Thread#join, Process.waitpid, etc...</p>
<p>I don't know if this patch can be implemented for win32, right<br>
now it's just dummy functions and that will be somebody elses<br>
job. But all pthreads platforms should eventually benefit.</p>
<p>Before this patch, the entropy-dependent script below takes 95MB<br>
consistently on my system. Now, depending on the amount of<br>
entropy on my system, it takes anywhere from 43MB to 75MB.</p>
<p>I'm using /dev/urandom to simulate real-world network latency<br>
variations. There is no improvement when using /dev/zero<br>
because the process is never idle.</p>
<p>require 'net/http'<br>
require 'digest/md5'<br>
Thread.abort_on_exception = true<br>
s = TCPServer.new('127.0.0.1', 0)<br>
len = 1024 * 1024 * 1024<br>
th = Thread.new do<br>
c = s.accept<br>
c.readpartial(16384)<br>
c.write("HTTP/1.0 200 OK\r\nContent-Length: #{len}\r\n\r\n")<br>
IO.copy_stream('/dev/urandom', c, len)<br>
c.close<br>
end</p>
<p>addr = s.addr<br>
Net::HTTP.start(addr[3], addr[1]) do |http|<br>
http.request_get('/') do |res|<br>
dig = Digest::MD5.new<br>
res.read_body { |buf|<br>
dig.update(buf)<br>
}<br>
puts dig.hexdigest<br>
end<br>
end</p>
<p>The above script is also dependent on net/protocol using<br>
read_nonblock. Ordinary IO objects will need IO#nonblock=true<br>
to see benefits (because they never hit rb_wait_for_single_fd)</p>
<ul>
<li>gc.c (rb_gc_inprogress): new function<br>
(rb_gc_step): ditto</li>
<li>internal.h: declare prototypes for new gc.c functions</li>
<li>thread_pthread.c (gvl_contended_p): new function</li>
<li>thread_win32.c (gvl_contended_p): ditto (dummy)</li>
<li>thread.c (rb_wait_for_single_fd w/ ppoll):<br>
use new functions to perform GC while GVL is uncontended<br>
and GC is lazy sweeping or incremental marking<br>
<a href="https://blade.ruby-lang.org/ruby-core/86265">[ruby-core:86265]</a></li>
</ul>
<pre><code>
2 part patch broken out
https://80x24.org/spew/20180429035007.6499-2-e@80x24.org/raw
https://80x24.org/spew/20180429035007.6499-3-e@80x24.org/raw
Also on my "sleepy-gc" git branch @ git://80x24.org/ruby.git
</code></pre> Ruby master - Feature #14718 (Open): Use jemalloc by default?https://redmine.ruby-lang.org/issues/147182018-04-27T16:14:10Zmperham (Mike Perham)mperham@gmail.com
<p>I know Sam opened <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Ship Ruby for Linux with jemalloc out-of-the-box (Closed)" href="https://redmine.ruby-lang.org/issues/9113">#9113</a> 4 years ago to suggest this but I'm revisiting the topic to see if there's any movement here for Ruby 2.6 or 2.7. I supply a major piece of Ruby infrastructure (Sidekiq) and I keep hearing over and over how Ruby is terrible with memory, a huge memory hog with their Rails apps. My users switch to jemalloc and a miracle occurs: their memory usage drops massively. Some data points:</p>
<p><a href="https://twitter.com/brandonhilkert/status/987400365627801601" class="external">https://twitter.com/brandonhilkert/status/987400365627801601</a><br>
<a href="https://twitter.com/d_jones/status/989866391787335680" class="external">https://twitter.com/d_jones/status/989866391787335680</a><br>
<a href="https://github.com/mperham/sidekiq/issues/3824#issuecomment-383072469" class="external">https://github.com/mperham/sidekiq/issues/3824#issuecomment-383072469</a></p>
<p>Redis moved to jemalloc many years ago and it solved all of their memory issues too. Their conclusion: the glibc allocator "sucks really really hard". <a href="http://oldblog.antirez.com/post/everything-about-redis-24.html" class="external">http://oldblog.antirez.com/post/everything-about-redis-24.html</a></p>
<p>This is a real pain point for the entire Rails community and would improve Ruby's reputation immensely if we can solve this problem.</p> Ruby master - Feature #14625 (Open): yield_self accepts an argument, calling to_prochttps://redmine.ruby-lang.org/issues/146252018-03-23T08:04:36Zirohiroki (Hiroki Yoshioka)
<p>Currently, yield_self doesn't accept any argument other than a block.</p>
<p>But there are situations where I would like to pass a method object to yield_self.<br>
e.g.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">result</span> <span class="o">=</span> <span class="n">collection</span>
<span class="p">.</span><span class="nf">yield_self</span><span class="p">(</span><span class="o">&</span><span class="nb">method</span><span class="p">(</span><span class="ss">:filter1</span><span class="p">))</span>
<span class="p">.</span><span class="nf">yield_self</span><span class="p">(</span><span class="o">&</span><span class="nb">method</span><span class="p">(</span><span class="ss">:filter2</span><span class="p">))</span>
</code></pre>
<p>Of course, we can get the same result with</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">result</span> <span class="o">=</span> <span class="n">filter2</span><span class="p">(</span><span class="n">filter1</span><span class="p">(</span><span class="n">collection</span><span class="p">))</span>
</code></pre>
<p>but the order of reading/writing doesn't match the order of thinking.</p>
<p>My request is for yield_self to accept a proc-ish object and call to_proc on it so that we can write the code as shown below, which is more readable.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">result</span> <span class="o">=</span> <span class="n">collection</span>
<span class="p">.</span><span class="nf">yield_self</span><span class="p">(</span><span class="nb">method</span> <span class="ss">:filter1</span><span class="p">)</span>
<span class="p">.</span><span class="nf">yield_self</span><span class="p">(</span><span class="nb">method</span> <span class="ss">:filter2</span><span class="p">)</span>
</code></pre> Ruby master - Feature #14602 (Open): Version of dig that raises error if a key is not presenthttps://redmine.ruby-lang.org/issues/146022018-03-13T18:29:57Zamcaplan (Ariel Caplan)ariel.caplan@mail.yu.edu
<p>Currently, if I have a hash like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">{</span>
<span class="ss">:name</span> <span class="o">=></span> <span class="p">{</span>
<span class="ss">:first</span> <span class="o">=></span> <span class="s2">"Ariel"</span><span class="p">,</span>
<span class="ss">:last</span> <span class="o">=></span> <span class="s2">"Caplan"</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
<p>and I want to navigate confidently and raise a KeyError if something is missing, I can do:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">hash</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="ss">:name</span><span class="p">).</span><span class="nf">fetch</span><span class="p">(</span><span class="ss">:first</span><span class="p">)</span>
</code></pre>
<p>Unfortunately, the length of the name, combined with the need to repeat the method name every time, means most programmers are more likely to do this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">hash</span><span class="p">[</span><span class="ss">:name</span><span class="p">][</span><span class="ss">:first</span><span class="p">]</span>
</code></pre>
<p>which leads to many unexpected errors.</p>
<p>The Hash#dig method made it easy to access methods safely from a nested hash; I'd like to have something similar for access without error protection, and I'd think the most natural name would be Hash#dig!. It would work like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">hash</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">:name</span> <span class="o">=></span> <span class="p">{</span>
<span class="ss">:first</span> <span class="o">=></span> <span class="s2">"Ariel"</span><span class="p">,</span>
<span class="ss">:last</span> <span class="o">=></span> <span class="s2">"Caplan"</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nb">hash</span><span class="p">.</span><span class="nf">dig!</span><span class="p">(</span><span class="ss">:name</span><span class="p">,</span> <span class="ss">:first</span><span class="p">)</span> <span class="c1"># => Ariel</span>
<span class="nb">hash</span><span class="p">.</span><span class="nf">dig!</span><span class="p">(</span><span class="ss">:name</span><span class="p">,</span> <span class="ss">:middle</span><span class="p">)</span> <span class="c1"># raises KeyError (key not found: :middle)</span>
<span class="nb">hash</span><span class="p">.</span><span class="nf">dig!</span><span class="p">(</span><span class="ss">:name</span><span class="p">,</span> <span class="ss">:first</span><span class="p">,</span> <span class="ss">:foo</span><span class="p">)</span> <span class="c1"># raises TypeError (String does not have #dig! method)</span>
</code></pre> Ruby master - Bug #14582 (Open): Unable to use `method__entry` and `method_return` tracing probes...https://redmine.ruby-lang.org/issues/145822018-03-07T06:23:00Zguilhermereiscampos (Guilherme Reis Campos)guilhermekbsa@gmail.com
<p>Hi,</p>
<p>I am trying to use dtrace/systemtap probes and not being able to use it after the 2.5. The 2.4 version works fine. I was hoping this was fixed on 2.6-preview, but apparently not (just downloaded dev and tested).</p>
<p>I tried on OSX using dtrace and also on ubuntu (vagrant).</p>
<pre><code># test.rb
class Foo
def bar
100.times { "Bar" }
end
end
foo = Foo.new
foo.bar
# test.stp
probe process("/home/vagrant/.rbenv/versions/2.4.0/bin/ruby").mark("method__entry") # you will need to change this to your ruby path of your version.
{
printf("%s => %s.%s in %s:%d\n", thread_indent(1), kernel_string($arg1),kernel_string($arg2),kernel_string($arg3),$arg4);
}
probe process("/home/vagrant/.rbenv/versions/2.4.0/bin/ruby").mark("method__return")
{
printf("%s <= %s.%s in %s:%d\n", thread_indent(-1), kernel_string($arg1),kernel_string($arg2),kernel_string($arg3),$arg4);
}
</code></pre>
<p>dtrace was something similar to it.</p>
<p>I was expecting to see this output:</p>
<pre><code># lots of calls
# ....
# then:
4090 ruby(9667): <= Gem::Specification.unresolved_deps in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/2.4.0/rubygems/specification.rb:1298
4095 ruby(9667): => MonitorMixin.mon_exit in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/2.4.0/monitor.rb:197
4100 ruby(9667): => MonitorMixin.mon_check_owner in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/2.4.0/monitor.rb:247
4104 ruby(9667): <= MonitorMixin.mon_check_owner in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/2.4.0/monitor.rb:251
4109 ruby(9667): <= MonitorMixin.mon_exit in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/2.4.0/monitor.rb:204
4283 ruby(9667): <= Kernel.require in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55
4303 ruby(9667): <= Kernel.require in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55
0 ruby(9667): => Foo.bar in test.rb:3
16 ruby(9667): <= Foo.bar in test.rb:5
</code></pre>
<p>(The output above is 2.4)</p>
<p>my ruby (all versions that I tested) was install with rb-env:</p>
<pre><code>RUBY_CONFIGURE_OPTS='--enable-dtrace --disable-install-doc' rbenv install 2.5.0
</code></pre>
<p>I am happy to provide details if required. I'd also be happy to fix it if I have guidance.</p>
<p>Thanks,</p> Ruby master - Feature #14411 (Open): URI#secure?https://redmine.ruby-lang.org/issues/144112018-01-27T14:52:52Zartur86 (Artur *)
<p>I wonder if some predicate method (say #secure?) could be added to URI::Generic class. Currently the only way to query if uri is secure is:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">uri</span><span class="p">.</span><span class="nf">instance_of?</span><span class="p">(</span><span class="no">URI</span><span class="o">::</span><span class="no">HTTPS</span><span class="p">)</span>
</code></pre>
<p>Inspired by this question: <a href="https://stackoverflow.com/questions/2212735/ruby-checking-if-uri-is-https" class="external">https://stackoverflow.com/questions/2212735/ruby-checking-if-uri-is-https</a></p> Ruby master - Feature #14348 (Open): win32ole: enable using coclass-es with multiple IDispatch im...https://redmine.ruby-lang.org/issues/143482018-01-10T11:34:49Zgraywolf (Gray Wolf)
<p>Currently win32ole requires coclass to directly implement (one) IDispatch. That<br>
works fine for</p>
<pre><code>coclass Good {
[default] interface GoodIface2;
interface GoodIface1;
};
interface GoodIface1 : IDispatch {
// snip
};
interface GoodIface2 : GoodIface1 {
// snip
};
</code></pre>
<p>however, it fails to work for the following</p>
<pre><code>coclass Bad {
[default] interface BadIface1;
interface BadIface2;
};
interface BadIface1 : IDispatch {
// snip
};
interface BadIface2 : IDispatch {
// snip
};
</code></pre>
<p>I suspect it's because when you ask for <code>IDispatch</code> of <code>Bad</code>, it doesn't know<br>
which one to give you (but I'm no COM expert so correct me if I'm wrong).</p>
<p>Now, please let's not discuss if classes like that are good idea or not (I<br>
think they are not), fact is they do exists and simple patch allows using them<br>
with ruby's win32ole.</p>
<p>Attached patch adds new <code>iface</code> keyword argument which let's you pick interface<br>
to acquire (it must still implement <code>IDispatch</code>). Documentation also says that<br>
you <em>very</em> likely do <em>NOT</em> need to use this argument.</p>
<p>Usage in my particular case would look like this:</p>
<pre><code>LIBNAME = 'xxx'
TYPELIB = WIN32OLE_TYPELIB.new(LIBNAME)
lic = 'xxxx'
foo = WIN32OLE.new(
TYPELIB.ole_type.find { |t| t.name == 'Foo' },
nil,
license: lic,
iface: '{00000000-0000-0000-0000-000000000000}'
)
foo.Bar(1, 2, 'foobar')
</code></pre>
<p>as you can see, except for the need to specify the interface, it works exactly<br>
same as normal classes.</p>
<p>Please consider for merge <code>^_^</code></p> Ruby master - Misc #14190 (Open): What are the semantics of $SAFE?https://redmine.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 - Feature #14079 (Open): Validate argument list without calling methodhttps://redmine.ruby-lang.org/issues/140792017-11-04T18:25:54Znate00 (Nate Sullivan)
<p>I would find it useful to check whether a list of arguments matches a method signature, but without calling the method.</p>
<p>I'd like to check the arguments list using a method called, for example, <code>respond_to_arguments?</code>. Here's an example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Foobar</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">baz</span><span class="p">(</span><span class="n">str</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># Foobar.baz accepts 1 argument, not 0 or 2:</span>
<span class="no">Foobar</span><span class="p">.</span><span class="nf">respond_to_arguments?</span><span class="p">(</span><span class="ss">:baz</span><span class="p">,</span> <span class="s2">"one"</span><span class="p">,</span> <span class="s2">"two"</span><span class="p">)</span> <span class="c1"># => false</span>
<span class="no">Foobar</span><span class="p">.</span><span class="nf">respond_to_arguments?</span><span class="p">(</span><span class="ss">:baz</span><span class="p">,</span> <span class="s2">"one"</span><span class="p">)</span> <span class="c1"># => true</span>
<span class="no">Foobar</span><span class="p">.</span><span class="nf">respond_to_arguments?</span><span class="p">(</span><span class="ss">:baz</span><span class="p">)</span> <span class="c1"># => false</span>
<span class="c1"># Indeed, we get an ArgumentError if we pass 0 or 2 arguments:</span>
<span class="no">Foobar</span><span class="p">.</span><span class="nf">baz</span><span class="p">(</span><span class="s2">"one"</span><span class="p">,</span> <span class="s2">"two"</span><span class="p">)</span> <span class="c1"># raises ArgumentError</span>
<span class="no">Foobar</span><span class="p">.</span><span class="nf">baz</span><span class="p">(</span><span class="s2">"one"</span><span class="p">)</span> <span class="c1"># success!</span>
<span class="no">Foobar</span><span class="p">.</span><span class="nf">baz</span> <span class="c1"># raises ArgumentError</span>
</code></pre>
<p>My use case is a background job processing system. It works like this: I call <code>MyWorker.perform_async</code> with some arguments; the arguments are serialized and put into a queue; and then a background worker takes those arguments from the queue, deserializes them and passes them to <code>MyWorker.perform</code>. If I passed invalid arguments, I don't know they were invalid until the background worker tries to call <code>perform</code>. But I'd like to know immediately when I call <code>perform_async</code>.</p>
<p>Perhaps a <code>respond_to_arguments_missing?</code> method would be required also.</p>
<p>Maybe <code>respond_to_arguments?</code> is a bad name. You could reasonably assume that it takes the same optional second parameter as <code>respond_to?</code> (i.e., <code>include_all</code>), but my proposal doesn't support an optional second parameter.</p>
<p>Thank you for your consideration!</p> Ruby master - Misc #14037 (Open): Writing doxygen document comments to static functionshttps://redmine.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 - Feature #13881 (Open): Use getcontext/setcontext on OS Xhttps://redmine.ruby-lang.org/issues/138812017-09-08T09:10:50Znaruse (Yui NARUSE)naruse@airemix.jp
<p>getcontext/setcontext is first appeared on OS X 10.5 but deprecated on 10.6.<br>
It seems because POSIX removed them from recent specs.</p>
<p>IEEE Std 1003.1, 2004 Edition says makecontext's use of function declarators with empty parentheses<br>
is an obsolescent feature.<br>
<a href="http://pubs.opengroup.org/onlinepubs/009695399/functions/makecontext.html" class="external">http://pubs.opengroup.org/onlinepubs/009695399/functions/makecontext.html</a></p>
<p>Then POSIX.1-2008 removed those functions.</p>
<p>But OS X 10.13 still has them maybe because some essential applications uses them for co-routines.<br>
Therefore we can use them for performance.</p>
<pre><code>diff --git a/configure.in b/configure.in
index 08e109317f..3e75eb3cf2 100644
--- a/configure.in
+++ b/configure.in
@@ -1142,8 +1142,6 @@ AS_CASE(["$target_os"],
ac_cv_header_syscall_h=no
])
AS_IF([test $macosx_10_5 = yes], [
- ac_cv_func_getcontext=no
- ac_cv_func_setcontext=no
], [
AC_DEFINE(BROKEN_SETREUID, 1)
AC_DEFINE(BROKEN_SETREGID, 1)
diff --git a/cont.c b/cont.c
index c86095775c..f94883ef02 100644
--- a/cont.c
+++ b/cont.c
@@ -65,7 +65,15 @@
#ifndef _WIN32
#include <unistd.h>
#include <sys/mman.h>
-#include <ucontext.h>
+# ifdef __APPLE__
+/* avoid deprecated maks on ucontext.h */
+int getcontext(ucontext_t *);
+void makecontext(ucontext_t *, void (*)(), int, ...);
+int setcontext(const ucontext_t *);
+int swapcontext(ucontext_t * __restrict, const ucontext_t * __restrict);
+# else
+# include <ucontext.h>
+# endif
#endif
#define RB_PAGE_SIZE (pagesize)
#define RB_PAGE_MASK (~(RB_PAGE_SIZE - 1))
</code></pre> Ruby master - Feature #13763 (Open): Trigger "unused variable warning" for unused variables in pa...https://redmine.ruby-lang.org/issues/137632017-07-24T12:16:29Zrovf (Ronald Fischer)ynnor@mm.st
<p>Consider the following program nowa.rb:</p>
<pre><code>def foo(a)
end
%w(x).each {|y|}
foo(1)
z=5
</code></pre>
<p>If I syntax-check it with <em>ruby -cw nowa.rb</em> I get the following warning:</p>
<pre><code>nowa.rb:5: warning: assigned but unused variable - z
</code></pre>
<p>Ruby complains about z, but does not complain about a and y, even though these are also variables which receive a value which never is used. I suggest to issue a warning in these cases too.</p>
<p>Tested with: ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-cygwin]</p> Ruby master - Feature #12928 (Open): Use socket conect_timeout in net stdlib for open_timeouthttps://redmine.ruby-lang.org/issues/129282016-11-13T10:32:38Zxiewenwei (xie wenwei)xiewenwei@gmail.com
<p>Current net/http and net/pop use Timeout.timeout to tigger open_timeout event.<br>
Timeout.timeout is slow. It will create and destroy a thread every time.<br>
Timeout.timeout is also dangerous. see [[http://www.mikeperham.com/2015/05/08/timeout-rubys-most-dangerous-api/]]</p>
<p>It is more effective and safe to use socket timeout to accomplish this.<br>
Follow is the changes need to do.</p>
<ol>
<li>Replace TCPSocket.open with Socket.new</li>
<li>Use socket.connect_nonblock and IO.select to connect and trigger timeout event.</li>
</ol>
<p>The pull request is here:<br>
[[https://github.com/ruby/ruby/pull/1480]]</p> Ruby master - Misc #12911 (Open): Translate docshttps://redmine.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 - Bug #12689 (Open): Thread isolation of $~ and $_https://redmine.ruby-lang.org/issues/126892016-08-19T06:37:18Zheadius (Charles Nutter)headius@headius.com
<p>We are debating what is correct behavior now, and what should be correct behavior in the future, for the thread-visibility of the special variables <code>%~</code> and <code>$_</code></p>
<p>We have several examples from <a href="https://github.com/jruby/jruby/issues/3031" class="external">https://github.com/jruby/jruby/issues/3031</a> that seem to exhibit conflicting behavior...or at least the behavior is unexpected in many cases.</p>
<pre><code>$ ruby23 -e 'p = proc { p $~; "foo" =~ /foo/ }; Thread.new {p.call}.join; Thread.new{p.call}.join'
nil
nil
$ ruby23 -e 'def foo; proc { p $~; "foo" =~ /foo/ }; end; p = foo; Thread.new {p.call}.join; Thread.new{p.call}.join'
nil
#<MatchData "foo">
$ ruby23 -e 'p = proc { p $~; "foo" =~ /foo/ }; def foo(p); Thread.new {p.call}.join; Thread.new{p.call}.join; end; foo(p)'
nil
#<MatchData "foo">
$ ruby23 -e 'class Foo; P = proc { p $~; "foo" =~ /foo/ }; def foo; Thread.new {P.call}.join; Thread.new{P.call}.join; end; end; Foo.new.foo'
nil
#<MatchData "foo">
$ ruby23 -e 'def foo; p = proc { p $~; "foo" =~ /foo/ }; Thread.new {p.call}.join; Thread.new{p.call}.join; end; foo'
nil
nil
$ ruby23 -e 'def foo; p = proc { p $~; "foo" =~ /foo/ }; bar(p); end; def bar(p); Thread.new {p.call}.join; Thread.new{p.call}.join; end; foo'
nil
#<MatchData "foo">
</code></pre>
<p>These cases exhibit some oddities in whether $~ (and presumably $_) are shared across threads.</p>
<p>The immediate thought is that they should be both frame and thread-local...but ko1 points out that such a change would break cases like this:</p>
<pre><code>def foo
/foo/ =~ 'foo'
Proc.new{
p $~
}
end
Thread.new{
foo.call
}.join
</code></pre>
<p>So there's a clear conflict here. Users sometimes expect the $~ value to be shared across threads (at least for read, as in ko1's example) and sometimes do not want it shared at all (as in the case of <a href="https://github.com/jruby/jruby/issues/3031" class="external">https://github.com/jruby/jruby/issues/3031</a></p>
<p>Now we discuss.</p> Ruby master - Feature #12625 (Open): TypeError.assert, ArgumentError.asserthttps://redmine.ruby-lang.org/issues/126252016-07-24T23:36:24Zeike.rb (Eike Dierks)eike@inter.net
<p>I am well aware that ruby is not typed (and so for a good reason)</p>
<p>But sometimes it makes sense to check the types (or values) of arguments upfront.<br>
(It actually helps to narrow down your arguments to the known)</p>
<p>I'd like to suggest an extension to all the Error types.<br>
(I should obviously come up with a gem first, but you get me)</p>
<p>I frequently write (in the prologue)<br>
raise TypeError.new(...) unless SomeClass === arg</p>
<p>I suggest to extend TypeError so that I could write instead:<br>
TypeError.assert(msg)(SomeClass, arg)<br>
and i'd expect that to raise the exception in the calling frame (which can be done via the binding?)</p>
<p>We might want to do the same for ArgumentError:<br>
ArgumentError.assert(msg){|arg| arg.nil?}<br>
ArgumentError.assert('too low'){|arg| arg<0}</p>
<p>But obviously, this api is just a first shot.</p>
<p>I'm with you: we can't check args at compile time.<br>
But checking args at runtime<br>
should be done via well known verses.</p>
<p>added bonus:<br>
we might want to make that a domain language.<br>
We could attach the argument checking rules to the method.</p>
<p>This might help in generating automated testing rules.</p>
<hr>
<p>No one wants types.<br>
but annotating types helps a lot.</p>
<p>It helps in documenting the code.<br>
It helps in making the code more foolproof.</p>
<pre><code>def foo(arg)
TypeError.assert(String, arg) # should raise in the foo frame if arg is not of type String
...
end
</code></pre> Ruby master - Feature #12589 (Open): VM performance improvement proposalhttps://redmine.ruby-lang.org/issues/125892016-07-18T03:24:41Zvmakarov (Vladimir Makarov)
<p>Hello. I'd like to start a big MRI project but I don't want to<br>
disrupt somebody else plans. Therefore I'd like to have MRI<br>
developer's opinion on the proposed project or information if somebody<br>
is already working on an analogous project.</p>
<p>Basically I want to improve overall MRI VM performance:</p>
<ul>
<li>
<p>First of all, I'd like to change VM insns and move from<br>
<strong>stack-based</strong> insns to <strong>register transfer</strong> ones. The idea behind<br>
it is to decrease VM dispatch overhead as approximately 2 times<br>
less RTL insns are necessary than stack based insns for the same<br>
program (for Ruby it is probably even less as a typical Ruby program<br>
contains a lot of method calls and the arguments are passed through<br>
the stack).</p>
<p>But <em>decreasing memory traffic</em> is even more important advantage<br>
of RTL insns as an RTL insn can address temporaries (stack) and<br>
local variables in any combination. So there is no necessity to<br>
put an insn result on the stack and then move it to a local<br>
variable or put variable value on the stack and then use it as an<br>
insn operand. Insns doing more also provide a bigger scope for C<br>
compiler optimizations.</p>
<p>The biggest changes will be in files compile.c and insns.def (they<br>
will be basically rewritten). <strong>So the project is not a new VM<br>
machine. MRI VM is much more than these 2 files.</strong></p>
<p>The disadvantage of RTL insns is a bigger insn memory footprint<br>
(which can be upto 30% more) although as I wrote there are fewer<br>
number of RTL insns.</p>
<p>Another disadvantage of RTL insns <em>specifically</em> for Ruby is that<br>
insns for call sequences will be basically the same stack based<br>
ones but only bigger as they address the stack explicitly.</p>
</li>
<li>
<p>Secondly, I'd like to <strong>combine some frequent insn sequences</strong> into<br>
bigger insns. Again it decreases insn dispatch overhead and<br>
memory traffic even more. Also it permits to remove some type<br>
checking.</p>
<p>The first thing on my mind is a sequence of a compare insn and a<br>
branch and using immediate operands besides temporary (stack) and<br>
local variables. Also it is not a trivial task for Ruby as the<br>
compare can be implemented as a method.</p>
</li>
</ul>
<p>I already did some experiments. RTL insns & combining insns permits<br>
to speed the following micro-benchmark in more 2 times:</p>
<pre><code>i = 0
while i<30_000_000 # benchmark loop 1
i += 1
end
</code></pre>
<p>The generated RTL insns for the benchmark are</p>
<pre><code>== disasm: #<ISeq:<main>@while.rb>======================================
== catch table
| catch type: break st: 0007 ed: 0020 sp: 0000 cont: 0020
| catch type: next st: 0007 ed: 0020 sp: 0000 cont: 0005
| catch type: redo st: 0007 ed: 0020 sp: 0000 cont: 0007
|------------------------------------------------------------------------
local table (size: 2, temp: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] i
0000 set_local_val 2, 0 ( 1)
0003 jump 13 ( 2)
0005 jump 13
0007 plusi <callcache>, 2, 2, 1, -1 ( 3)
0013 btlti 7, <callcache>, -1, 2, 30000000, -1 ( 2)
0020 local_ret 2, 0 ( 3)
</code></pre>
<p>In this experiment I ignored trace insns (that is another story) and a<br>
complication that a integer compare insn can be re-implemented as a<br>
Ruby method. Insn bflti is combination of LT immediate compare and<br>
branch true.</p>
<p>A modification of fib benchmark is sped up in 1.35 times:</p>
<pre><code>def fib_m n
if n < 1
1
else
fib_m(n-1) * fib_m(n-2)
end
end
fib_m(40)
</code></pre>
<p>The RTL code of fib_m looks like</p>
<pre><code>== disasm: #<ISeq:fib_m@fm.rb>==========================================
local table (size: 2, temp: 3, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] n<Arg>
0000 bflti 10, <callcache>, -1, 2, 1, -1 ( 2)
0007 val_ret 1, 16
0010 minusi <callcache>, -2, 2, 1, -2 ( 5)
0016 simple_call_self <callinfo!mid:fib_m, argc:1, FCALL|ARGS_SIMPLE>, <callcache>, -1
0020 minusi <callcache>, -3, 2, 2, -3
0026 simple_call_self <callinfo!mid:fib_m, argc:1, FCALL|ARGS_SIMPLE>, <callcache>, -2
0030 mult <callcache>, -1, -1, -2, -1
0036 temp_ret -1, 16
</code></pre>
<p>In reality, the improvement of most programs probably will be about<br>
10%. That is because of very dynamic nature of Ruby (a lot of calls,<br>
checks for redefinition of basic type operations, checking overflows<br>
to switch to GMP numbers). For example, integer addition can not be<br>
less than about x86-64 17 insns out of the current 50 insns on the<br>
fast path. So even if you make the rest (33) insns 2 times faster,<br>
the improvement will be only 30%.</p>
<p>A very important part of MRI performance improvement is to make calls<br>
fast because there are a lot of them in Ruby but as I read in some<br>
Koichi Sasada's presentations he pays a lot of attention to it. So I<br>
don't want to touch it.</p>
<ul>
<li>
<p>Thirdly. I want to implement the insns as small inline functions<br>
for future AOT compiler, of course, if the projects described<br>
above are successful. It will permit easy AOT generation of C code<br>
which will be basically calls of the functions.</p>
<p>I'd like to implement AOT compiler which will generate a Ruby<br>
method code, call a C compiler to generate a binary shared code<br>
and load it into MRI for subsequent calls. The key is to minimize<br>
the compilation time. There are many approaches to do it but I<br>
don't want to discuss it right now.</p>
<p>C generation is easy and most portable implementation of AOT but<br>
in future it is possible to use GCC JIT plugin or LLVM IR to<br>
decrease overhead of C scanner/parser.</p>
<p>C compiler will see a bigger scope (all method insns) to do<br>
optimizations. I think using AOT can give another 10%<br>
improvement. It is not that big again because of dynamic nature<br>
of Ruby and any C compiler is not smart enough to figure out<br>
aliasing for typical generated C program.</p>
<p>The life with the performance point of view would be easy if Ruby<br>
did not permit to redefine basic operations for basic types,<br>
e.g. plus for integer. In this case we could evaluate types of<br>
operands and results using some data flow analysis and generate<br>
faster specialized insns. Still a gradual typing if it is<br>
introduced in future versions of Ruby would help to generate such<br>
faster insns.</p>
</li>
</ul>
<p>Again I wrote this proposal for discussion as I don't want to be in<br>
a position to compete with somebody else ongoing big project. It<br>
might be counterproductive for MRI development. Especially I don't<br>
want it because the project is big and long and probably will have a<br>
lot of tehcnical obstacles and have a possibilty to be a failure.</p> Ruby master - Feature #12435 (Open): Using connect_nonblock to open TCP connections in Net::HTTP#...https://redmine.ruby-lang.org/issues/124352016-05-28T19:57:30Zmohamedhafez (Mohamed Hafez)
<p>Hey all, I've got a pull request at <a href="https://github.com/ruby/ruby/pull/1370" class="external">https://github.com/ruby/ruby/pull/1370</a> to start using connect_nonblock to open the TCP socket in Net::HTTP#connect, instead of doing a blocking connect that uses Timeout.timeout to look for timeouts. Using connect_nonblock is more efficient since it doesn't involve spinning up a separate thread to watch for timeouts, and also it avoids the race conditions inherent in the use of Timeout.timeout, as detailed in <a href="http://blog.headius.com/2008/02/ruby-threadraise-threadkill-timeoutrb.html" class="external">http://blog.headius.com/2008/02/ruby-threadraise-threadkill-timeoutrb.html</a></p>
<p>Over the last few versions of ruby there have been analogous fixes accepted to do this for opening an SSL connection in Net::HTTP#connect, so I'm guessing this shouldn't be too controversial, unless there is some issue I'm not aware of that kept the maintainers from implementing this as well...</p> Ruby master - Feature #12173 (Open): `Time#till_now`https://redmine.ruby-lang.org/issues/121732016-03-14T16:57:25Zsawa (Tsuyoshi Sawada)
<p>It is very frequent to have a time instance:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="n">t</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span>
</code></pre>
<p>and then after some operations, do:</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="o">-</span> <span class="n">t</span>
</code></pre>
<p>I propose <code>Time#till_now</code>, which is equivalent to:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="k">class</span> <span class="nc">Time</span>
<span class="k">def</span> <span class="nf">till_now</span><span class="p">;</span> <span class="nb">self</span><span class="p">.</span><span class="nf">class</span><span class="p">.</span><span class="nf">now</span> <span class="o">-</span> <span class="nb">self</span> <span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>and similar methods can perhaps be defined on <code>Date</code> and <code>DateTime</code> classes as well. Another candidate for the method name is <code>until_now</code>.</p>
<p>Then we can do:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="n">t</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span>
<span class="c1"># some heavy operation</span>
<span class="nb">puts</span> <span class="s2">"It took </span><span class="si">#{</span><span class="n">t</span><span class="p">.</span><span class="nf">till_now</span><span class="si">}</span><span class="s2"> secs."</span>
</code></pre> Ruby master - Feature #12114 (Open): $VERBOSE = true is being ignoredhttps://redmine.ruby-lang.org/issues/121142016-02-26T11:18:06Zrovf (Ronald Fischer)ynnor@mm.st
<p>This programm correctly complains about "assigned but unused variable - p"</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1">#!/usr/bin/ruby -w</span>
<span class="nb">p</span><span class="o">=</span><span class="mi">1</span>
</code></pre>
<p>However, this one doesn't</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1">#!/usr/bin/ruby</span>
<span class="k">BEGIN</span> <span class="p">{</span><span class="vg">$VERBOSE</span> <span class="o">=</span> <span class="kp">true</span><span class="p">}</span>
<span class="nb">p</span><span class="o">=</span><span class="mi">1</span>
</code></pre>
<p>Setting <code>$VERBOSE</code> to true in a <code>BEGIN</code> block should have the same effect as providing it on the command line, but this is obviously not the case.</p> Ruby master - Feature #12086 (Open): using: option for instance_eval etc.https://redmine.ruby-lang.org/issues/120862016-02-19T07:34:02Zshugo (Shugo Maeda)
<p>Currently refinements can be activated only in toplevel or class/module definitions.<br>
If they can be activated in block-level, it's useful to implement internal DSLs.</p>
<p>How about to add a new option using: for Kernel#instance_eval and Moule#{class,module}_eval?</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">FixnumDivExt</span>
<span class="n">refine</span> <span class="no">Fixnum</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">/</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="n">quo</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> 0</span>
<span class="nb">instance_eval</span><span class="p">(</span><span class="ss">using: </span><span class="no">FixnumDivExt</span><span class="p">)</span> <span class="k">do</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> (1/2)</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> 0</span>
</code></pre>
<p>Proof-of-concept implementation is available at <a href="https://github.com/shugo/ruby/tree/eval_using" class="external">https://github.com/shugo/ruby/tree/eval_using</a>.</p>
<p>In my previous proposal before Ruby 2.0, refinements used in a class or module are<br>
implicitly activated by instance_eval and class_eval, but now I think it's better to<br>
explicitly specify refinements to be activated.</p>
<p>Considerations:</p>
<ul>
<li>In the PoC implementation, refined methods are not cached inline, and thus it decreases<br>
the performance of refined method call.<br>
If there is a way to guarantee that blocks never be evaluated in different environments,<br>
refined methods can be cached inline.</li>
<li>{instance,class,module}_exec cannot be extended in the same way, because they take arbitrary<br>
arguments and there's no way to distinguish an option hash from the last argument hash.</li>
</ul> Ruby master - Feature #11781 (Open): Would it be possible to alias .prepend() towards .unshift() ...https://redmine.ruby-lang.org/issues/117812015-12-07T10:12:22Zshevegen (Robert A. Heiler)shevegen@gmail.com
<p>Hello.</p>
<p>For Strings we can do:</p>
<pre><code>abc = 'world!'
abc[0,0] = 'Hello '
abc # => "Hello world!"
</code></pre>
<p>For Arrays we can do:</p>
<pre><code>abc = ['world!']
abc[0,0] = 'Hello '
abc # => ["Hello ", "world!"]
</code></pre>
<p>This is nice.</p>
<p>For Strings we can also use .prepend() to add to the beginning.</p>
<p>For Arrays, we have to use .unshift().</p>
<p>I have a hard time remembering .unshift though, .prepend() seems<br>
to be easier for me to remember.</p>
<p>I'd like to use both .prepend for Strings and Arrays; right now<br>
I have to use different names. I could alias prepend to unshift<br>
for class Array, but then I'd have to carry these modifications<br>
into my projects, which is not so good - I would prefer to just<br>
stick to what MRI is doing.</p>
<p>Could we have the alias .prepend() for class Array, meaning<br>
.unshift() too? That way I could use .prepend() for both Arrays<br>
and Strings.</p>
<p>Thanks for reading!</p> Ruby master - Feature #11690 (Open): Update Hash during multiple assignmenthttps://redmine.ruby-lang.org/issues/116902015-11-15T16:30:53Zdanielpclark (Daniel P. Clark)6ftdan@gmail.com
<p>Given that we can assign multiple variables at once</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="p">,</span><span class="n">c</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span>
</code></pre>
<p>It would be nice to be able to update a Hash during multiple assignment rather than replacing it. Currently</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">x</span> <span class="o">=</span> <span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">,</span> <span class="ss">b: </span><span class="mi">2</span><span class="p">}</span>
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="p">,</span><span class="n">z</span> <span class="o">=</span> <span class="p">{</span><span class="ss">c: </span><span class="mi">3</span><span class="p">},</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span>
<span class="n">x</span>
<span class="c1"># => {c: 3}</span>
</code></pre>
<p>What I propose is adding <code>Hash#update=</code> to permit updating during multiple assignment.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Hash</span>
<span class="k">def</span> <span class="nf">update</span><span class="o">=</span><span class="p">(</span><span class="n">h</span><span class="p">)</span>
<span class="n">update</span><span class="p">(</span><span class="n">h</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">x</span> <span class="o">=</span> <span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">,</span> <span class="ss">b: </span><span class="mi">2</span><span class="p">}</span>
<span class="n">x</span><span class="p">.</span><span class="nf">update</span><span class="p">,</span> <span class="n">y</span> <span class="p">,</span><span class="n">z</span> <span class="o">=</span> <span class="p">{</span><span class="ss">c: </span><span class="mi">3</span><span class="p">},</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span>
<span class="n">x</span>
<span class="c1"># => {a: 1, b: 2, c: 3}</span>
</code></pre>
<p>This would be most useful in scenarios where a method or proc return multiple values. When the method returns the values we don't normally know the key outside where the hash assignment is.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">example</span> <span class="o">=</span> <span class="nb">proc</span> <span class="p">{</span> <span class="p">[{</span><span class="ss">:hi</span> <span class="o">=></span> <span class="ss">:hello</span><span class="p">},</span> <span class="mi">5</span><span class="p">]</span> <span class="p">}</span>
<span class="nb">hash</span> <span class="o">=</span> <span class="p">{}</span>
<span class="c1"># Currently in Ruby with an Unknown key multiple assignment isn't an option</span>
<span class="nb">hash</span><span class="p">[</span><span class="sc">??</span><span class="p">?</span><span class="sc">?]</span><span class="p">,</span> <span class="n">current</span> <span class="o">=</span> <span class="n">example</span><span class="p">.</span><span class="nf">call</span>
<span class="c1"># We currently have to two step it</span>
<span class="n">result</span><span class="p">,</span> <span class="n">current</span> <span class="o">=</span> <span class="n">example</span><span class="p">.</span><span class="nf">call</span>
<span class="nb">hash</span><span class="p">.</span><span class="nf">update</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
</code></pre>
<p>But with <code>Hash#update=</code> we don't have to know the key.</p> Ruby master - Feature #11625 (Assigned): Unlock GVL for SHA1 calculationshttps://redmine.ruby-lang.org/issues/116252015-10-27T19:34:06Ztenderlovemaking (Aaron Patterson)tenderlove@ruby-lang.org
<p>I'm trying to calculate many sha1 checksums, but the current sha1 implementation doesn't unlock the GVL, so I can't do it in parallel. I've attached a patch that unlocks the GVL when calculating sha1sums so that I can do them in parallel.</p>
<p>The good point about this patch is that I can calculate sha1's in parallel. Here is the test code I'm using:</p>
<pre><code>require 'digest/sha1'
require 'thread'
Thread.abort_on_exception = true
THREADS = (ENV['THREADS'] || 1).to_i
store = 'x' * (ENV['SIZE'] || 1024).to_i
queue = Queue.new
600000.times do
queue << store
end
THREADS.times { queue << nil }
ts = THREADS.times.map {
Thread.new {
while work = queue.pop
Digest::SHA1.hexdigest(work)
end
}
}
ts.each(&:join)
</code></pre>
<p>Here is what the output looks like after I've applied the patch:</p>
<pre><code>[aaron@TC ruby (trunk)]$ THREADS=1 SIZE=4096 time ./ruby test.rb
22.62 real 21.78 user 0.66 sys
[aaron@TC ruby (trunk)]$ THREADS=4 SIZE=4096 time ./ruby test.rb
15.87 real 34.53 user 8.27 sys
[aaron@TC ruby (trunk)]$
</code></pre>
<p>The digests that I'm calculating are for fairly large strings, so this patch works well for me. The downsides are that it seems slightly slower (though I'm not sure that it's significant) with a single thread:</p>
<p>Test code:</p>
<pre><code>require 'benchmark/ips'
require 'digest/sha1'
Benchmark.ips do |x|
x.report('sha1') { Digest::SHA1.hexdigest('x' * 4096) }
end
</code></pre>
<p>Before my patch (higher numbers are better):</p>
<pre><code>[aaron@TC ruby (trunk)]$ ./ruby shaips.rb
Calculating -------------------------------------
sha1 2.604k i/100ms
-------------------------------------------------
sha1 27.441k (± 3.9%) i/s - 138.012k
</code></pre>
<p>After my patch:</p>
<pre><code>[aaron@TC ruby (trunk)]$ ./ruby shaips.rb
Calculating -------------------------------------
sha1 2.419k i/100ms
-------------------------------------------------
sha1 25.848k (± 2.8%) i/s - 130.626k
</code></pre>
<p>Other downside is that I changed the <code>update</code> method to dup strings so that the GVL can be safely released.</p>
<p>This patch pays off for me because of the size of the strings I'm working with, but I'm not sure if it's fine for the general case.</p> Ruby master - Misc #10983 (Open): Why blocks make Ruby methods 439% slower ?https://redmine.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 - Feature #10949 (Open): Time is WB unprotectedhttps://redmine.ruby-lang.org/issues/109492015-03-08T18:10:04Zsylvain.joyeux (Sylvain Joyeux)
<p>Ruby's built-in Time object is shady. Unfortunately, it is an object that can commonly be created in big numbers (think logs or stuff like that), and since they don't store relationship with other objects they are perfect candidate for the oldgen.</p>
<p>I don't really know if there is a kind of policy about which built-in Ruby objects should be sunny or not, so I just put this as a feature request (as opposed to having it as a bug)</p> Ruby master - Feature #10879 (Open): UnboundMethod#to_prochttps://redmine.ruby-lang.org/issues/108792015-02-21T19:56:44ZGondolin (Damien Robert)Damien.Olivier.Robert+ruby@gmail.com
<p>Since unbound methods from modules can now be bound to any object, I use them a lot.<br>
I think it would be very natural to be able to convert them to Proc:</p>
<pre><code>module UnboundMethod
def to_proc
return lambda do |obj,*args,&b|
self.bind(obj).call(*args,&b)
end
end
end
</code></pre>
<p>This would allow things like</p>
<pre><code>module Foo
def foo
self+"foo"
end
end
["bar","baz"].map(&Foo.instance_method(:foo)) => ["barfoo", "bazfoo"]
</code></pre> Ruby master - Feature #10755 (Open): Use rb_define_alias instead of rb_define_method for rb_cHashhttps://redmine.ruby-lang.org/issues/107552015-01-18T03:10:08Zgogotanaka (Kazuki Tanaka)mail@tanakakazuki.com
<p>Hi, there.</p>
<p>The main reason for using <code>rb_define_alias</code> is generating more prefer Document and making code more readable.</p>
<p>Is there any reason <code>rb_define_method</code> is prefered to <code>rb_define_alias</code>?<br>
If so, please let me know :)<br>
If not so, I'm gonna do same thing for other part of code.</p>
<p>I've sorted some methods in terms of <code>rb_define_alias</code> being very after original.</p> Ruby master - Feature #10728 (Open): Warning for Fixnum#size to use RbConfig::SIZEOF['long']https://redmine.ruby-lang.org/issues/107282015-01-10T11:42:23Zakr (Akira Tanaka)akr@fsij.org
<p>How about add a warning for Fixnum#size ?</p>
<pre><code>% ./ruby -e 'p 0.size'
-e:1: warning: Use RbConfig::SIZEOF['long'] instead of Fixnum#size
8
</code></pre>
<p>Currently it returns sizeof(long) which is 4 or 8.</p>
<p>However it is implementation detail and<br>
it may difficult to define it in Ruby implementations other than CRuby.</p>
<p>There is a way to obtain sizeof(long): RbConfig::SIZEOF['long']<br>
It works since Ruby 2.1.</p>
<pre><code>% ruby -rrbconfig/sizeof -e "p RbConfig::SIZEOF['long']"
8
</code></pre>
<p>So the warning is a migration path to use RbConfig::SIZEOF['long'].</p>
<p>Note that this may affect many code.<br>
So this issue may irritate many people.<br>
fixnum-size-search.txt is a search result in gems.</p> Ruby master - Feature #10589 (Open): [TracePoint API] Make THREAD_{BEGIN, END} events return some...https://redmine.ruby-lang.org/issues/105892014-12-11T16:27:00Zdeivid (David Rodríguez)
<p>Currently the :thread_begin and thread_end events return no context information at all</p>
<pre><code>TracePoint.trace(:thread_begin, :thread_end) do |tp|
puts "#{tp.defined_class}::#{tp.method_id}@#{tp.path}:#{tp.lineno}"
end
t = Thread.new do
sleep 1
end
t.join
</code></pre>
<p>prints just</p>
<pre><code>"Hi thread, ::@:0"
"Bye thread, ::@:0"
</code></pre>
<p>It'd be nice if they gave at least some file:line context information about the thread.</p>
<p>What do you think, <a class="user active user-mention" href="https://redmine.ruby-lang.org/users/17">@ko1 (Koichi Sasada)</a>? Would this be possible?</p>
<p>Thanks a lot</p> Ruby master - Feature #10519 (Open): TLS Renegotiationhttps://redmine.ruby-lang.org/issues/105192014-11-16T12:24:37Zbararchy (Bar Hofesh)bar.hofesh@safe-t.com
<p>Hello,</p>
<p>It seems that the ability to force renegotiation as a client is missing or not exposed.<br>
The ability is implemented in OpenSSL's s_client as the "R" character when the connection is established.<br>
It will be great if that can be exposed to ruby's OpenSSL::SSL::SSLSocket</p>
<p>Thanks,</p> Ruby master - Feature #10371 (Open): Use Thread#handle_interrupt in MonitorMixinhttps://redmine.ruby-lang.org/issues/103712014-10-12T06:41:48Znerdrew (Andrew Lazarus)nerdrew@gmail.com
<p>Now that ruby has Thread#handle_interrupt, MonitorMixin can always unlock the mutex even when a timeout exception is raised.</p>
<p>Currently, if a timeout exception is raised in MonitorMixin#mon_exit at just the wrong time, the @mon_owner is set to nil, but the @mon_mutex is still locked. ThreadError: deadlock; recursive locking is raised the next time the resource is accessed.</p> Ruby master - Feature #10251 (Open): URI: Support wildcards (globbing) in no_proxyhttps://redmine.ruby-lang.org/issues/102512014-09-17T17:24:01Zjustindossey (Justin Dossey)jbd@justindossey.com
<p>The current implementation of URI#find_proxy will only exclude exact matches when processing the no_proxy environment variable.</p>
<p>This diverges from the commonly-used no_proxy specification that supports globs (e.g. <em>.example.com, 192.168.</em>).</p>
<p>Adding globbing support (perhaps using File.fnmatch) would make URI behave the same as other implementations.</p> Ruby master - Feature #10237 (Open): Transform all elements of one Encoding into another Encoding...https://redmine.ruby-lang.org/issues/102372014-09-13T22:59:19Zshevegen (Robert A. Heiler)shevegen@gmail.com
<p>I find myself to sometimes have to convert one encoding to the other.</p>
<p>For string objects, this is trivial:</p>
<p>.encode()<br>
.force_encoding()</p>
<p>For reading in a file via File.readlines(), this is also<br>
simple because of stuff like:</p>
<p>File.readlines('test.txt', :encoding => 'ascii-8bit')</p>
<p>For Array and Hashes, however, this is a bit annoying for me.</p>
<p>I'd love to have an .encode method as well.</p>
<p>This method should try to convert all elements on an Array<br>
or a Hash to another encoding IF they are a string object.</p>
<p>I'd like to be able to treat Array and Hashes in the same<br>
way, so that I can e. g. convert a hash dictionary from<br>
one encoding to the other quickly.</p>
<p>It already is possible of course, with some extra lines<br>
of code, but I'd love to have a way to do so with just<br>
one method call.</p>
<p>:</p> Ruby master - Feature #9909 (Open): why shouldn't constant lookup check the nesting of module's namehttps://redmine.ruby-lang.org/issues/99092014-06-06T14:43:18Zrits (First Last)
<p>module A<br>
module B<br>
end<br>
end</p>
<p>above, B will have access to A's constants<br>
but below, it won't</p>
<p>module A::B<br>
end</p>
<p>is there a reason why the nesting of the name should not be part of the constant resolution algorithm?</p>
<p>when adding or reopening (deeply) nested modules/classes the :: syntax would be preferable, but you lose constant resolution</p> Ruby master - Misc #9724 (Open): Warnings in Ruby: allow per-file directives to i.e. suppress war...https://redmine.ruby-lang.org/issues/97242014-04-10T18:21:31Zshevegen (Robert A. Heiler)shevegen@gmail.com
<p>Hi,</p>
<p>A bit of intro.</p>
<p>I usually run all my ruby code with -w. I feel that it gives me some more security if the<br>
ruby parser does not have to think about ambiguous code.</p>
<p>Now this works perfect for my own code - I know what I have written, I know how to fix it,<br>
so my code runs fine.</p>
<p>Problem is other people who do not use the -w switch, and in doing so their stuff outputs<br>
a lot of warnings if I require their project and use them.</p>
<p>This is somewhat annoying and there is no real good way to fix it as far as I know.</p>
<p>Modifying $VERBOSE and setting it to nil is of no real help because it works globally.<br>
But I'd rather want something to be used on a per-file basis.</p>
<p>Would it be possible to enable something that could be used on a per file<br>
basis? Kernel.no_warnings, or Kernel.be_silent or something like this?</p> Ruby master - Feature #9613 (Open): Warn about unsafe ossl ciphershttps://redmine.ruby-lang.org/issues/96132014-03-08T03:04:48Zzzak (zzak _)
<p>As of r45274, we now have sane whitelist of available OpenSSL ciphers. However, this patch breaks backwards compatibility for any apps that use any ciphers not whitelisted.</p>
<a name="Solution"></a>
<h2 >Solution<a href="#Solution" class="wiki-anchor">¶</a></h2>
<ul>
<li>Implement a new class: OpenSSL::SSL::Ciphers
<ul>
<li>This class defines a constant for every whitelisted cipher used by DEFAULT_PARAMS[:ciphers]</li>
<li>Any constant not found within this class should raise a warning and report to the user</li>
</ul>
</li>
<li>Add an OpenSSL::SSL::Configuration class
<ul>
<li>Designed to default to no compression, and no sslv2/v3</li>
<li>Used by DEFAULT_PARAMS[:options]</li>
<li>This class may contain helper methods such as: #compression_enabled?</li>
</ul>
</li>
</ul>
<a name="Pros"></a>
<h2 >Pros<a href="#Pros" class="wiki-anchor">¶</a></h2>
<ul>
<li>We don't break anything, without warning users first</li>
<li>Maintaining future whitelist ciphers is easier</li>
<li>Future unsupported/blacklist ciphers are already dismissed</li>
<li>Users are able to extend cipher lists to support their needs (by adding a constant to OpenSSL::SSL::Ciphers)</li>
</ul>
<a name="Concerns"></a>
<h2 >Concerns<a href="#Concerns" class="wiki-anchor">¶</a></h2>
<p>I have discussed this with Martin, and we'd like to open up this discussion for feedback. We're particularly concerned about backporting r45274 as it breaks compatibility. We should also consider:</p>
<ul>
<li>Do we backport both patches or just the warning?</li>
<li>Should we bother backporting deprecation warnings?
<ul>
<li>Since r45274 is not a security fix, do we consider this a bug?</li>
<li>Rails only introduces deprecation notices in new minor releases (ie: Ruby-2.2.0)</li>
</ul>
</li>
<li>r45274 is a major change that could break existing apps, even considering security</li>
</ul> Ruby master - Feature #9401 (Open): Yet another syntax for literal anonymous functions (lambdas)https://redmine.ruby-lang.org/issues/94012014-01-12T10:44:54Zalexeymuranov (Alexey Muranov)
<p>Please do not be angry at me and just close this proposal if it does not look interesting. It comes from my aesthetic dissatisfaction with the <code>->(x){ ... }</code> literal anonymous function notation and from my amateurish interest in lambda calculus.</p>
<p>Here is a yet another syntax for literal anonymous functions (lambdas) that i propose:</p>
<pre><code>f = {\ x => x*x }
f[1] # => 1
f[2] # => 4
</code></pre>
<p>It looks a bit like a hash on purpose: i think that a hash is a "function in extension" and a lambda is a "function in intension" (see, for example, in <a href="http://www.classes.cs.uchicago.edu/archive/2004/spring/15300-1/docs/lambda-intro.pdf" class="external">these notes</a>). The backslash stands for "lambda", like in Haskell.</p> Ruby master - Feature #9174 (Open): value receiving block for Hash#has_key?https://redmine.ruby-lang.org/issues/91742013-11-29T06:33:11Zrits (First Last)
<p>Seems useful to be able to check for presence (as opposed to falsyness) and receive the value</p>
<p>class Hash<br>
def has_key?(key, &block)<br>
val = fetch(key){return false}<br>
block.(val) if block<br>
true<br>
end<br>
end</p>
<p>if h.has_key? :key do |val|</p>
<h1></h1>
<p>end; else</p>
<h1></h1>
<p>end</p> Ruby master - Feature #8404 (Open): virtual, hooked or read only global variabels for ruby only c...https://redmine.ruby-lang.org/issues/84042013-05-14T21:19:29ZHanmac (Hans Mackowiak)hanmac@gmx.de
<p>currently pure virtual or hooked global variables can only be defined with cFunctions like rb_define_virtual_variable</p>
<p>i think it would be cool if this would be possible in Ruby code too</p> Ruby master - Feature #8272 (Open): Transfer feature tracking to CommonRubyhttps://redmine.ruby-lang.org/issues/82722013-04-16T05:45:34Zheadius (Charles Nutter)headius@headius.com
<p>If my proposal in <a class="issue tracker-2 status-2 priority-4 priority-default" title="Feature: Proposal for moving to a more visible, formal process for feature requests (Assigned)" href="https://redmine.ruby-lang.org/issues/8271">#8271</a> is accepted, we'll need to:</p>
<ol>
<li>
<p>Document in appropriate places that CommonRuby is the place to file and track feature changes. Examples of such places: bugs.ruby-lang.org top-level page, pages for the existing "trunk" and version-specific Redmine projects, ruby-lang.org pages that describe how to file bugs.</p>
</li>
<li>
<p>Decide how to handle the "feature" flag in the current trackers. This may include solutions like removing it entirely (perhaps infeasible if existing features are not migrated to CommonRuby), adding a warning or error when "feature" is selected to encourage users to file under CommonRuby instead, or automatically putting "feature" issues under CommonRuby at submission time.</p>
</li>
<li>
<p>(optional) Migrate existing open features to CommonRuby.</p>
</li>
</ol>