Ruby Issue Tracking System: Issueshttps://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112021-12-29T13:16:58ZRuby Issue Tracking System
Redmine Ruby master - Feature #18450 (Assigned): Force break in prettyprinthttps://bugs.ruby-lang.org/issues/184502021-12-29T13:16:58Zfirasalkhalil (Firas al-Khalil)
<a name="Abstract"></a>
<h1 >Abstract<a href="#Abstract" class="wiki-anchor">¶</a></h1>
<p>Support force-breaking a group in the std's <a href="https://github.com/ruby/prettyprint" class="external">prettyprint</a></p>
<a name="Background"></a>
<h1 >Background<a href="#Background" class="wiki-anchor">¶</a></h1>
<p>There is a need to forcibly break a group and transform breakables into<br>
newlines. The library doesn't provide this possibility, directly, through<br>
its public API.</p>
<a name="Proposal"></a>
<h1 >Proposal<a href="#Proposal" class="wiki-anchor">¶</a></h1>
<p>Add a single convenience function to the library's public class <code>PrettyPrint</code></p>
<a name="Implementation"></a>
<h1 >Implementation<a href="#Implementation" class="wiki-anchor">¶</a></h1>
<p>An implementation was submitted to the project's github repository as a<br>
<a href="https://github.com/ruby/prettyprint/pull/2" class="external">pull request</a>.</p>
<p>Here's the patch:</p>
<pre><code>diff --git a/lib/prettyprint.rb b/lib/prettyprint.rb
index 188c2e6..1d675a7 100644
--- a/lib/prettyprint.rb
+++ b/lib/prettyprint.rb
@@ -236,6 +236,14 @@ class PrettyPrint
end
end
+ # This says "force a line break here".
+ #
+ # It will force the current group's "breakables" to break.
+ def break
+ breakable
+ current_group.break
+ end
+
# Groups line break hints added in the block. The line break hints are all
# to be used or not.
#
diff --git a/test/test_prettyprint.rb b/test/test_prettyprint.rb
index 27e7198..cf889d1 100644
--- a/test/test_prettyprint.rb
+++ b/test/test_prettyprint.rb
@@ -518,4 +518,31 @@ End
end
+
+class Break < Test::Unit::TestCase # :nodoc:
+ def format()
+ PrettyPrint.format(''.dup) {|q|
+ q.group {
+ q.text 'abc'
+ q.breakable
+ q.text 'def'
+ q.group {
+ q.break
+ q.text 'ghi'
+ }
+ q.breakable
+ q.text 'jkl'
+ }
+ }
+ end
+
+ def test_00_04
+ expected = <<'End'.chomp
+abc def
+ghi jkl
+End
+ assert_equal(expected, format())
+ end
+end
+
</code></pre>
<a name="Evaluation"></a>
<h1 >Evaluation<a href="#Evaluation" class="wiki-anchor">¶</a></h1>
<p>It's a simple implementation with no caveats.</p>
<a name="Discussion"></a>
<h1 >Discussion<a href="#Discussion" class="wiki-anchor">¶</a></h1>
<p>Even though it's a simple functionality, and the implementation is straightforward,<br>
getting to this point is not that obvious. This is why it might be helpful for other<br>
users who face such a need.</p>
<p>Indeed, an issue was <a href="https://github.com/ruby/prettyprint/issues/1" class="external">opened</a> not so long ago,<br>
and the proposed solution worked but not quite as expected. The provided implementation<br>
works as expected without tampering with the API's internals, and it's proven in production<br>
environment.</p>
<a name="Summary"></a>
<h1 >Summary<a href="#Summary" class="wiki-anchor">¶</a></h1>
<p>This is a feature request for the <code>prettyprint</code> library: adding support for <em>force breaking</em><br>
a group. An implementation is provided as both a patch and a PR on github.</p> Ruby master - Misc #17569 (Open): `uri` lib maintainershiphttps://bugs.ruby-lang.org/issues/175692021-01-22T15:48:33Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>I’d like to merge <a href="https://github.com/ruby/uri/pull/15" class="external">https://github.com/ruby/uri/pull/15</a> but it is an API change. I would release v1.0.0. <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/271">@akr (Akira Tanaka)</a> is the official maintainer of <code>uri</code>… Is he still interested in this role? Otherwise we could put “Ruby core team” in the listing…</p> Ruby master - Feature #17473 (Open): Make Pathname to embedded class of Rubyhttps://bugs.ruby-lang.org/issues/174732020-12-26T12:00:42Zhsbt (Hiroshi SHIBATA)hsbt@ruby-lang.org
<p>pathname is one of most useful utility class of Ruby. I'm happy to use Pathname without require it.</p>
<p>Any thought?</p> Ruby master - Feature #17297 (Assigned): Feature: Introduce Pathname.mktmpdirhttps://bugs.ruby-lang.org/issues/172972020-10-30T15:09:41Zschneems (Richard Schneeman)
<p>When I want to create a tmpdir I often want to manipulate it as a pathname. By introducing Pathname.mktmpdir I can get this behavior.</p>
<p>Currently I must:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Dir</span><span class="p">.</span><span class="nf">mktmpdir</span> <span class="k">do</span> <span class="o">|</span><span class="n">dir</span><span class="o">|</span>
<span class="n">dir</span> <span class="o">=</span> <span class="no">Pathname</span><span class="p">(</span><span class="n">dir</span><span class="p">)</span>
<span class="c1"># ... code</span>
<span class="k">end</span>
</code></pre>
<p>I would like to be able to instead:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Pathname</span><span class="p">.</span><span class="nf">mktmpdir</span> <span class="k">do</span> <span class="o">|</span><span class="n">dir</span><span class="o">|</span>
<span class="c1"># ... code</span>
<span class="k">end</span>
</code></pre>
<p>Diff:</p>
<pre><code>$ git diff master
diff --git a/ext/pathname/lib/pathname.rb b/ext/pathname/lib/pathname.rb
index e6fb90277d..ec32e7d611 100644
--- a/ext/pathname/lib/pathname.rb
+++ b/ext/pathname/lib/pathname.rb
@@ -597,3 +597,20 @@ def rmtree
end
end
+class Pathname # * tmpdir *
+ # Creates a tmp directory and wraps the returned path in a Pathname object.
+ #
+ # See Dir.mktmpdir
+ def self.mktmpdir
+ require 'tmpdir' unless defined?(Dir.mktmpdir)
+ if block_given?
+ Dir.mktmpdir do |dir|
+ dir = self.new(dir)
+ yield dir
+ end
+ else
+ self.new(Dir.mktmpdir)
+ end
+ end
+end
+
diff --git a/test/pathname/test_pathname.rb b/test/pathname/test_pathname.rb
index 43cef4849f..8edcccf666 100644
--- a/test/pathname/test_pathname.rb
+++ b/test/pathname/test_pathname.rb
@@ -1272,6 +1272,14 @@ def test_s_glob_3args
}
end
+ def test_mktmpdir
+ Pathname.mktmpdir do |dir|
+ assert_equal Pathname(dir), dir
+ assert dir.directory?
+ assert dir.exist?
+ end
+ end
+
def test_s_getwd
wd = Pathname.getwd
assert_kind_of(Pathname, wd)
</code></pre>
<p>Github link: <a href="https://github.com/ruby/ruby/pull/3709" class="external">https://github.com/ruby/ruby/pull/3709</a></p> Ruby master - Feature #17296 (Assigned): Feature: Pathname#chmod use FileUtils.chmod instead of Filehttps://bugs.ruby-lang.org/issues/172962020-10-30T15:08:09Zschneems (Richard Schneeman)
<p>The <code>FileUtils.chmod</code> provides the same numerical interface as <code>File.chmod</code> and it also includes a "symbolic mode" interface. With this patch you'll be able to run this 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="s2">"bin/compile"</span><span class="p">).</span><span class="nf">chmod</span><span class="p">(</span><span class="s2">"+x"</span><span class="p">)</span>
</code></pre>
<p>I believe that this is backwards compatible with the existing implementation and all changes are an extension. The only difference between File.chmod and FileUtils.chmod I could find is they have different return values and the previous implementation of <code>Pathname#chmod</code> returned the result of the <code>File.chmod</code> call. From the docs <code>File.chmod</code> returns the number of files modified, since we're only ever able to pass in a maximum of one file through this interface, the return value will always be a <code>1</code> or an exception if the file does not exist.</p>
<p>I checked and the exceptions when the file does not exist match:</p>
<pre><code>irb(main):004:0> File.chmod(0444, "doesnotexist.txt")
Traceback (most recent call last):
6: from /Users/rschneeman/.rubies/ruby-2.7.2/bin/irb:23:in `<main>'
5: from /Users/rschneeman/.rubies/ruby-2.7.2/bin/irb:23:in `load'
4: from /Users/rschneeman/.rubies/ruby-2.7.2/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
3: from (irb):3
2: from (irb):4:in `rescue in irb_binding'
1: from (irb):4:in `chmod'
Errno::ENOENT (No such file or directory @ apply2files - doesnotexist.txt)
irb(main):005:0> FileUtils.chmod(0444, "doesnotexist.txt")
Traceback (most recent call last):
10: from /Users/rschneeman/.rubies/ruby-2.7.2/bin/irb:23:in `<main>'
9: from /Users/rschneeman/.rubies/ruby-2.7.2/bin/irb:23:in `load'
8: from /Users/rschneeman/.rubies/ruby-2.7.2/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
7: from (irb):4
6: from (irb):5:in `rescue in irb_binding'
5: from /Users/rschneeman/.rubies/ruby-2.7.2/lib/ruby/2.7.0/fileutils.rb:1016:in `chmod'
4: from /Users/rschneeman/.rubies/ruby-2.7.2/lib/ruby/2.7.0/fileutils.rb:1016:in `each'
3: from /Users/rschneeman/.rubies/ruby-2.7.2/lib/ruby/2.7.0/fileutils.rb:1017:in `block in chmod'
2: from /Users/rschneeman/.rubies/ruby-2.7.2/lib/ruby/2.7.0/fileutils.rb:1346:in `chmod'
1: from /Users/rschneeman/.rubies/ruby-2.7.2/lib/ruby/2.7.0/fileutils.rb:1346:in `chmod'
Errno::ENOENT (No such file or directory @ apply2files - doesnotexist.txt)
</code></pre>
<p>If you're open to changing the interface of the return value my preference would be to return <code>self</code> from this method so that it can be chained. Otherwise this current patch is a smaller change.</p>
<p>Diff:</p>
<pre><code>$ git diff master
diff --git a/ext/pathname/lib/pathname.rb b/ext/pathname/lib/pathname.rb
index e6fb90277d..cb6e32d9ac 100644
--- a/ext/pathname/lib/pathname.rb
+++ b/ext/pathname/lib/pathname.rb
@@ -585,6 +585,15 @@ def mkpath
nil
end
+ # Changes file permissions.
+ #
+ # See FileUtils.chmod
+ def chmod(mode)
+ require 'fileutils'
+ FileUtils.chmod(mode, self)
+ return 1
+ end
+
# Recursively deletes a directory, including all directories beneath it.
#
# See FileUtils.rm_r
diff --git a/ext/pathname/pathname.c b/ext/pathname/pathname.c
index f71cec1b25..6778d4f102 100644
--- a/ext/pathname/pathname.c
+++ b/ext/pathname/pathname.c
@@ -12,7 +12,6 @@ static ID id_binwrite;
static ID id_birthtime;
static ID id_blockdev_p;
static ID id_chardev_p;
-static ID id_chmod;
static ID id_chown;
static ID id_ctime;
static ID id_directory_p;
@@ -552,20 +551,6 @@ path_mtime(VALUE self)
return rb_funcall(rb_cFile, id_mtime, 1, get_strpath(self));
}
-/*
- * call-seq:
- * pathname.chmod(mode_int) -> integer
- *
- * Changes file permissions.
- *
- * See File.chmod.
- */
-static VALUE
-path_chmod(VALUE self, VALUE mode)
-{
- return rb_funcall(rb_cFile, id_chmod, 2, mode, get_strpath(self));
-}
-
/*
* call-seq:
* pathname.lchmod(mode_int) -> integer
@@ -1448,7 +1433,6 @@ path_f_pathname(VALUE self, VALUE str)
* - #birthtime
* - #ctime
* - #mtime
- * - #chmod(mode)
* - #lchmod(mode)
* - #chown(owner, group)
* - #lchown(owner, group)
@@ -1495,6 +1479,7 @@ path_f_pathname(VALUE self, VALUE str)
* === Utilities
*
* These methods are a mixture of Find, FileUtils, and others:
+ * - #chmod(mode)
* - #find(&block)
* - #mkpath
* - #rmtree
@@ -1542,7 +1527,6 @@ Init_pathname(void)
rb_define_method(rb_cPathname, "birthtime", path_birthtime, 0);
rb_define_method(rb_cPathname, "ctime", path_ctime, 0);
rb_define_method(rb_cPathname, "mtime", path_mtime, 0);
- rb_define_method(rb_cPathname, "chmod", path_chmod, 1);
rb_define_method(rb_cPathname, "lchmod", path_lchmod, 1);
rb_define_method(rb_cPathname, "chown", path_chown, 2);
rb_define_method(rb_cPathname, "lchown", path_lchown, 2);
@@ -1618,7 +1602,6 @@ InitVM_pathname(void)
id_birthtime = rb_intern("birthtime");
id_blockdev_p = rb_intern("blockdev?");
id_chardev_p = rb_intern("chardev?");
- id_chmod = rb_intern("chmod");
id_chown = rb_intern("chown");
id_ctime = rb_intern("ctime");
id_directory_p = rb_intern("directory?");
diff --git a/test/pathname/test_pathname.rb b/test/pathname/test_pathname.rb
index 43cef4849f..5673691231 100644
--- a/test/pathname/test_pathname.rb
+++ b/test/pathname/test_pathname.rb
@@ -823,6 +823,11 @@ def test_chmod
path.chmod(0444)
assert_equal(0444, path.stat.mode & 0777)
path.chmod(old)
+
+ skip "Windows has different symbolic mode" if /mswin|mingw/ =~ RUBY_PLATFORM
+ path.chmod("u=wrx,g=rx,o=x")
+ assert_equal(0751, path.stat.mode & 0777)
+ path.chmod(old)
}
end
</code></pre>
<p>Github link: <a href="https://github.com/ruby/ruby/pull/3708" class="external">https://github.com/ruby/ruby/pull/3708</a></p> Ruby master - Feature #17295 (Assigned): Feature: Create a directory and file with Pathname#touchhttps://bugs.ruby-lang.org/issues/172952020-10-30T15:06:39Zschneems (Richard Schneeman)
<p>Right now if a developer wants to create a file and is not sure if the path exists yet or not they must:</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="s2">"/a/b/c/d.txt"</span><span class="p">).</span><span class="nf">tap</span> <span class="p">{</span><span class="o">|</span><span class="nb">p</span><span class="o">|</span> <span class="nb">p</span><span class="p">.</span><span class="nf">dirname</span><span class="p">.</span><span class="nf">mkpath</span><span class="p">;</span> <span class="no">FileUtils</span><span class="p">.</span><span class="nf">touch</span><span class="p">(</span><span class="nb">p</span><span class="p">)}</span>
</code></pre>
<p>After this patch a developer can instead call:</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="s2">"/a/b/c/d.txt"</span><span class="p">).</span><span class="nf">touch</span>
</code></pre>
<p>An alternative name for this behavior could be <code>mkfile</code> but I think it is confusing to have a <code>mkfile</code> and a <code>mkpath</code> where one creates a directory and one creates a file.</p>
<p>Diff:</p>
<pre><code>$ git diff master
diff --git a/ext/pathname/lib/pathname.rb b/ext/pathname/lib/pathname.rb
index e6fb90277d..2ed02a6633 100644
--- a/ext/pathname/lib/pathname.rb
+++ b/ext/pathname/lib/pathname.rb
@@ -585,6 +585,27 @@ def mkpath
nil
end
+ # Creates a file and the full path to the file including any intermediate directories that don't yet
+ # exist.
+ #
+ # Example:
+ #
+ # Dir.exist?("/a/b/c") # => false
+ #
+ # p = Pathname.new("/a/b/c/d.txt")
+ # p.file? => false
+ # p.touch
+ # p.file? => true
+ #
+ # Dir.exist?("/a/b/c") # => true
+ def touch
+ require 'fileutils'
+ dirname.mkpath
+
+ FileUtils.touch(self)
+ self
+ end
+
# Recursively deletes a directory, including all directories beneath it.
#
# See FileUtils.rm_r
diff --git a/test/pathname/test_pathname.rb b/test/pathname/test_pathname.rb
index 43cef4849f..3c518cc3da 100644
--- a/test/pathname/test_pathname.rb
+++ b/test/pathname/test_pathname.rb
@@ -1394,6 +1394,14 @@ def test_mkpath
}
end
+ def test_touch
+ with_tmpchdir('rubytest-pathname') {|dir|
+ Pathname("a/b/c/d.txt").touch
+ assert_file.directory?("a/b/c")
+ assert_file.file?("a/b/c/d.txt")
+ }
+ end
+
def test_rmtree
with_tmpchdir('rubytest-pathname') {|dir|
Pathname("a/b/c/d").mkpath
</code></pre>
<p>Github link: <a href="https://github.com/ruby/ruby/pull/3706" class="external">https://github.com/ruby/ruby/pull/3706</a></p> Ruby master - Feature #17294 (Assigned): Feature: Allow method chaining with Pathname#mkpath Path...https://bugs.ruby-lang.org/issues/172942020-10-30T15:04:06Zschneems (Richard Schneeman)
<p>Currently in my code when I want to create a pathname object and create a path at the same time I must use tap</p>
<pre><code>path = Pathname.new("/tmp/new").tap(&:mkpath)
</code></pre>
<p>I think it would be cleaner to be able to chain on the results of these methods instead:</p>
<pre><code>path = Pathname.new("/tmp/new").mkpath
</code></pre>
<p>This is a change in return value but after research on github I do not believe many (if any) are relying on the current behavior to return nil <a href="https://github.com/search?l=&p=1&q=.mkpath+language%3ARuby&ref=advsearch&type=Code" class="external">https://github.com/search?l=&p=1&q=.mkpath+language%3ARuby&ref=advsearch&type=Code</a>.</p>
<p>Here is my diff:</p>
<pre><code>$ git diff master schneems/return-self-pathname
diff --git a/ext/pathname/lib/pathname.rb b/ext/pathname/lib/pathname.rb
index e6fb90277d..f1eb1e00ae 100644
--- a/ext/pathname/lib/pathname.rb
+++ b/ext/pathname/lib/pathname.rb
@@ -582,7 +582,7 @@ class Pathname # * FileUtils *
def mkpath
require 'fileutils'
FileUtils.mkpath(@path)
- nil
+ self
end
# Recursively deletes a directory, including all directories beneath it.
@@ -593,7 +593,7 @@ def rmtree
# File::Path provides "mkpath" and "rmtree".
require 'fileutils'
FileUtils.rm_r(@path)
- nil
+ self
end
end
diff --git a/test/pathname/test_pathname.rb b/test/pathname/test_pathname.rb
index 43cef4849f..149fe15c3a 100644
--- a/test/pathname/test_pathname.rb
+++ b/test/pathname/test_pathname.rb
@@ -1389,7 +1389,8 @@ def test_find
def test_mkpath
with_tmpchdir('rubytest-pathname') {|dir|
- Pathname("a/b/c/d").mkpath
+ path = Pathname("a/b/c/d")
+ assert_equal(path, path.mkpath)
assert_file.directory?("a/b/c/d")
}
end
@@ -1398,7 +1399,8 @@ def test_rmtree
with_tmpchdir('rubytest-pathname') {|dir|
Pathname("a/b/c/d").mkpath
assert_file.exist?("a/b/c/d")
- Pathname("a").rmtree
+ path = Pathname("a")
+ assert_equal(path, path.rmtree)
assert_file.not_exist?("a")
}
end
</code></pre>
<p>Github PR: <a href="https://github.com/ruby/ruby/pull/3705" class="external">https://github.com/ruby/ruby/pull/3705</a>. If accepted I will make a pr to update the tests here as well <a href="https://github.com/ruby/rbs/blob/b0dee64fdd00cc41c0729fa2c239fc2dcb9c3b18/test/stdlib/Pathname_test.rb#L456-L463" class="external">https://github.com/ruby/rbs/blob/b0dee64fdd00cc41c0729fa2c239fc2dcb9c3b18/test/stdlib/Pathname_test.rb#L456-L463</a>.</p> Ruby master - Feature #17173 (Open): open-uri で ciphers を設定したいhttps://bugs.ruby-lang.org/issues/171732020-09-16T04:55:19Zznz (Kazuhiro NISHIYAMA)
<p>Debian GNU/Linux 10 (buster) の OpenSSL 1.1.1d の環境だと <a href="https://www.famitsu.com" class="external">https://www.famitsu.com</a> で <code>dh key too small</code> になってつながらないのですが、 <code>ciphers</code> に <code>DEFAULT:!DH</code> を設定するとつながるので、 <code>open-uri</code> 経由でも <code>ciphers</code> を設定したいです。</p>
<p>curl での確認:</p>
<pre><code>% curl --head https://www.famitsu.com/
curl: (35) error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small
zsh: exit 35 curl --head https://www.famitsu.com/
% curl --ciphers 'DEFAULT:!DH' --head https://www.famitsu.com/
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Wed, 16 Sep 2020 04:48:25 GMT
Content-Type: text/html
Connection: keep-alive
Vary: Accept-Encoding
Accept-Ranges: bytes
Vary: Accept-Encoding
Strict-Transport-Security: max-age=60
</code></pre>
<p>ruby での確認:</p>
<pre><code>% ruby -r open-uri -e 'open("https://www.famitsu.com/")'
Traceback (most recent call last):
13: from -e:1:in `<main>'
12: from /usr/lib/ruby/2.5.0/open-uri.rb:35:in `open'
11: from /usr/lib/ruby/2.5.0/open-uri.rb:735:in `open'
10: from /usr/lib/ruby/2.5.0/open-uri.rb:165:in `open_uri'
9: from /usr/lib/ruby/2.5.0/open-uri.rb:224:in `open_loop'
8: from /usr/lib/ruby/2.5.0/open-uri.rb:224:in `catch'
7: from /usr/lib/ruby/2.5.0/open-uri.rb:226:in `block in open_loop'
6: from /usr/lib/ruby/2.5.0/open-uri.rb:755:in `buffer_open'
5: from /usr/lib/ruby/2.5.0/open-uri.rb:337:in `open_http'
4: from /usr/lib/ruby/2.5.0/net/http.rb:909:in `start'
3: from /usr/lib/ruby/2.5.0/net/http.rb:920:in `do_start'
2: from /usr/lib/ruby/2.5.0/net/http.rb:985:in `connect'
1: from /usr/lib/ruby/2.5.0/net/protocol.rb:44:in `ssl_socket_connect'
/usr/lib/ruby/2.5.0/net/protocol.rb:44:in `connect_nonblock': SSL_connect returned=1 errno=0 state=error: dh key too small (OpenSSL::SSL::SSLError)
zsh: exit 1 ruby -r open-uri -e 'open("https://www.famitsu.com/")'
% ruby -r net/http -e 'http=Net::HTTP.new("www.famitsu.com", 443); http.use_ssl=true; http.ciphers="DEFAULT:!DH"; p http.get("/")'
#<Net::HTTPOK 200 OK readbody=true>
</code></pre>
<p><a href="https://www.ssllabs.com/ssltest/analyze.html?d=www.famitsu.com" class="external">https://www.ssllabs.com/ssltest/analyze.html?d=www.famitsu.com</a> によると Cipher Suites は</p>
<pre><code># TLS 1.2 (suites in server-preferred order)
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x9f) DH 1024 bits FS WEAK 256
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x9e) DH 1024 bits FS WEAK 128
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x6b) DH 1024 bits FS WEAK 256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x67) DH 1024 bits FS WEAK 128
TLS_RSA_WITH_AES_256_GCM_SHA384 (0x9d) WEAK 256
TLS_RSA_WITH_AES_128_GCM_SHA256 (0x9c) WEAK 128
TLS_RSA_WITH_AES_256_CBC_SHA256 (0x3d) WEAK 256
TLS_RSA_WITH_AES_128_CBC_SHA256 (0x3c) WEAK 128
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) ECDH secp384r1 (eq. 7680 bits RSA) FS 256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) ECDH secp384r1 (eq. 7680 bits RSA) FS 128
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028) ECDH secp384r1 (eq. 7680 bits RSA) FS WEAK 256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) ECDH secp384r1 (eq. 7680 bits RSA) FS WEAK 128
</code></pre>
<p>となっていて、 Handshake Simulation では</p>
<pre><code>Chrome 80 / Win 10 R RSA 2048 (SHA256) TLS 1.2 TLS_RSA_WITH_AES_256_GCM_SHA384 No FS
Firefox 73 / Win 10 R RSA 2048 (SHA256) TLS 1.2 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ECDH secp256r1 FS
OpenSSL 1.1.1c R RSA 2048 (SHA256) TLS 1.2 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 DH 1024 FS
</code></pre>
<p>のようになっていて、 <code>TLS_DHE_RSA_WITH_AES_256_GCM_SHA384</code> が選ばれて DH 1024 bit を拒否するクライアントからは繋らない設定になっているサーバーがあるようです。(<code>dh key too small</code> で web 検索すると同様の設定のサーバーは他にもあるようです。)</p> Ruby master - Misc #17154 (Open): Update Pathname Documentation to Clarify Expected Behaviorhttps://bugs.ruby-lang.org/issues/171542020-09-05T02:29:29Zresperat (Ralph Esperat)
<p>I would like to suggest adding a sentence to the documentation for <a href="https://ruby-doc.org/stdlib-2.7.1/libdoc/pathname/rdoc/Pathname.html" class="external">Pathname</a> to make clear the unusual behavior of <code>Pathname#+</code> when an absolute path is included in the arguments. In such a situation, <code>Pathname#+</code> drops the paths prior to the last absolute path which I understand to be the intended behavior, but it is not obviously intended, only showing up tangentially as an example in the documentation.</p>
<pre><code>p3 = p1 + "/etc/passwd" # Pathname:/etc/passwd
</code></pre>
<p>The Pathname documentation states that " <strong>All functionality</strong> from File, FileTest, and some from Dir and FileUtils is included, <strong>in an unsurprising way</strong> ..." and later when referring to core methods such as <code>Pathname#+</code> "These methods are <strong>effectively manipulating a String</strong> , because that's all a path is." However, similar uses of both <a href="https://ruby-doc.org/core-2.7.1/File.html" class="external">File</a> and <a href="https://ruby-doc.org/core-2.7.1/String.html" class="external">String</a> would produce the expected result of including all of the arguments:</p>
<pre><code>s1 = "/usr"
s2 = s1 + "/etc/passwd" # "/usr/etc/passwd"
f1 = File.new("/usr" + "/etc/passwd") # (No such file or directory @ rb_sysopen - /usr/etc/passwd)
</code></pre>
<p>A bug report was previously filed to "fix" this functionality (<a class="issue tracker-1 status-6 priority-4 priority-default closed" title="Status: Rejected" href="https://bugs.ruby-lang.org/issues/15564">Bug #15564: Pathname#+(pathpart) returns pathpart when pathpart is absolute</a>), not understanding it to be intentional. Other common help websites such as <a href="https://stackoverflow.com/questions/12464361/concatenating-absolute-paths-with-the-pathname-class" class="external">Stack Overflow</a> also show users who do not expect this behavior from this method. Adding a statement to the documentation for the <a href="https://ruby-doc.org/stdlib-2.7.1/libdoc/pathname/rdoc/Pathname.html#method-i-2B" class="external">Pathname#+</a> method will make it clear to users exactly what to expect and that this is the intended behavior. I would suggest simply the following, the first sentence of which is already present:</p>
<p><code>Appends a pathname fragment to self to produce a new Pathname object. If an absolute path is provided as any of the arguments, discards all arguments prior to the last absolute path provided.</code></p>
<p>I appreciate your consideration of this request.</p>
<p>ruby -v: ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]</p> Ruby master - Feature #16985 (Open): Improve `pp` for `Hash` and `String`https://bugs.ruby-lang.org/issues/169852020-06-25T17:28:06Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>Could we improve <code>pp</code> for <code>Hash</code> and <code>String</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">pp</span><span class="p">({</span><span class="ss">hello: </span><span class="s1">'My name is "Marc-André"'</span><span class="p">})</span>
<span class="c1"># =></span>
<span class="p">{</span><span class="ss">hello: </span><span class="s1">'My name is "Marc-André"'</span><span class="p">}</span>
<span class="c1"># instead of</span>
<span class="p">{</span><span class="ss">:hello</span><span class="o">=></span><span class="s2">"My name is </span><span class="se">\"</span><span class="s2">Marc-André</span><span class="se">\"</span><span class="s2">"</span><span class="p">}</span>
</code></pre>
<p>If any key is non-symbol, they would continue to be output as <code><key> => <value></code>. If a string contains single quotes, or characters that need escaping (e.g. <code>"\n"</code>), current format would be used.</p>
<p>I'll gladly provide a PR if this is deemed acceptable.</p>
<p>I would even like this for <code>String#inspect</code> and <code>Hash#inspect</code> but it's not clear if this could lead to much incompatibility (maybe test suites?)</p> Ruby master - Feature #16937 (Assigned): Add DNS over HTTP to Resolvhttps://bugs.ruby-lang.org/issues/169372020-06-07T23:46:44Zdrbrain (Eric Hodel)drbrain@segment7.net
<p>This adds a DNS over HTTP resolver at Resolv::DoH</p>
<p>It obeys RFC8484 with respect to Cache-Control and Age behavior, but does not use HTTP2 as ruby does not have an HTTP2 client.</p>
<p>It does not allow configuration of the Net::HTTP instance beyond timeouts, but I am willing to add more configuration if this is desired.</p> Ruby master - Feature #13385 (Open): [PATCH] Make Resolv::DNS::Name validation similar to host an...https://bugs.ruby-lang.org/issues/133852017-03-29T09:17:33Zpavel.mikhailyuk@gmail.com (Pavel Mikhailyuk)
<a name="Abstract"></a>
<h1 >Abstract<a href="#Abstract" class="wiki-anchor">¶</a></h1>
<p>Add validations similar to <strong>host</strong> and <strong>dig</strong> commands to <code>Resolv::DNS::Name.create</code></p>
<a name="Background"></a>
<h1 >Background<a href="#Background" class="wiki-anchor">¶</a></h1>
<p><code>Resolv::DNS::Name.create(str)</code> does not make any domain name validation.<br>
So it returns false positive results for queries like</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="no">Resolv</span><span class="o">::</span><span class="no">DNS</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">getresources</span><span class="p">(</span><span class="s1">'.gmail....com'</span><span class="p">,</span> <span class="no">Resolv</span><span class="o">::</span><span class="no">DNS</span><span class="o">::</span><span class="no">Resource</span><span class="o">::</span><span class="no">IN</span><span class="o">::</span><span class="no">MX</span><span class="p">)</span>
<span class="o">=></span> <span class="p">[</span><span class="c1">#<Resolv::DNS::Resource::IN::MX:0x007fc3107ecf68 @exchange=#<Resolv::DNS::Name: alt1.gmail-smtp-in.l.google.com.>, @preference=10, @ttl=3600>,</span>
<span class="c1">#<Resolv::DNS::Resource::IN::MX:0x007fc313013730 @exchange=#<Resolv::DNS::Name: alt2.gmail-smtp-in.l.google.com.>, @preference=20, @ttl=3600>,</span>
<span class="c1">#<Resolv::DNS::Resource::IN::MX:0x007fc313011f20 @exchange=#<Resolv::DNS::Name: gmail-smtp-in.l.google.com.>, @preference=5, @ttl=3600>,</span>
<span class="c1">#<Resolv::DNS::Resource::IN::MX:0x007fc313010a30 @exchange=#<Resolv::DNS::Name: alt4.gmail-smtp-in.l.google.com.>, @preference=40, @ttl=3600>,</span>
<span class="c1">#<Resolv::DNS::Resource::IN::MX:0x007fc313012858 @exchange=#<Resolv::DNS::Name: alt3.gmail-smtp-in.l.google.com.>, @preference=30, @ttl=3600>]</span>
</code></pre>
<p>while</p>
<pre><code class="text syntaxhl" data-language="text">~ dig .gmail....com MX
dig: '.gmail....com' is not a legal name (empty label)
</code></pre>
<p>I added basic RFC validations in <code>Resolv::DNS::Label.split</code> to get <code>ArgumentError</code> with messages similar to <strong>host</strong> and <strong>dig</strong> commands.</p>
<a name="Pull-request"></a>
<h1 >Pull request<a href="#Pull-request" class="wiki-anchor">¶</a></h1>
<p><a href="https://github.com/ruby/ruby/pull/1551" class="external">https://github.com/ruby/ruby/pull/1551</a></p> Ruby master - Feature #13047 (Assigned): Use String literal instead of `String#+` for multiline p...https://bugs.ruby-lang.org/issues/130472016-12-17T14:21:49Zmtsmfm (Fumiaki Matsushima)mtsmfm@gmail.com
<p>Multiline pretty-printing of multiline strings is introduced. (<a href="https://bugs.ruby-lang.org/issues/12664" class="external">https://bugs.ruby-lang.org/issues/12664</a>)</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">></span> <span class="n">pp</span> <span class="s2">"bundler.rb"</span><span class="o">=></span> <span class="s2">"module Bundler</span><span class="se">\n</span><span class="s2"> BundlerError = Class.new(Exception)</span><span class="se">\n</span><span class="s2"> def self.setup</span><span class="se">\n</span><span class="s2"> end</span><span class="se">\n</span><span class="s2">end</span><span class="se">\n</span><span class="s2">"</span>
<span class="p">{</span><span class="s2">"bundler.rb"</span><span class="o">=></span>
<span class="s2">"module Bundler</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span>
<span class="s2">" BundlerError = Class.new(Exception)</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span>
<span class="s2">" def self.setup</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span>
<span class="s2">" end</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span>
<span class="s2">"end</span><span class="se">\n</span><span class="s2">"</span><span class="p">}</span>
</code></pre>
<p>It is awesome but we can use String literal instead of <code>String#+</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">></span> <span class="n">pp</span> <span class="s2">"bundler.rb"</span><span class="o">=></span> <span class="s2">"module Bundler</span><span class="se">\n</span><span class="s2"> BundlerError = Class.new(Exception)</span><span class="se">\n</span><span class="s2"> def self.setup</span><span class="se">\n</span><span class="s2"> end</span><span class="se">\n</span><span class="s2">end</span><span class="se">\n</span><span class="s2">"</span>
<span class="p">{</span><span class="s2">"bundler.rb"</span><span class="o">=></span>
<span class="s2">"module Bundler</span><span class="se">\n</span><span class="s2">"</span> <span class="p">\</span>
<span class="s2">" BundlerError = Class.new(Exception)</span><span class="se">\n</span><span class="s2">"</span> <span class="p">\</span>
<span class="s2">" def self.setup</span><span class="se">\n</span><span class="s2">"</span> <span class="p">\</span>
<span class="s2">" end</span><span class="se">\n</span><span class="s2">"</span> <span class="p">\</span>
<span class="s2">"end</span><span class="se">\n</span><span class="s2">"</span><span class="p">}</span>
</code></pre>
<p>It seems that <code>pp</code> want to output evaluable snippet but we can override <code>String#+</code> so it may not work well.</p>
<p>Non-broken String will be:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">></span> <span class="n">pp</span> <span class="s2">"bundler.rb"</span><span class="o">=></span> <span class="s2">"module Bundler</span><span class="se">\n</span><span class="s2">end</span><span class="se">\n</span><span class="s2">"</span>
<span class="p">{</span><span class="s2">"bundler.rb"</span><span class="o">=></span> <span class="s2">"module Bundler</span><span class="se">\n</span><span class="s2">"</span> <span class="s2">"end</span><span class="se">\n</span><span class="s2">"</span><span class="p">}</span>
</code></pre>
<p>How do you think?</p>
<hr>
<p>I tried to write patch but I can't find a way to append "" to broken line only by current PP's API.</p> Ruby master - Feature #12497 (Assigned): GMP version of divmod may be slowerhttps://bugs.ruby-lang.org/issues/124972016-06-16T17:04:12Zmame (Yusuke Endoh)mame@ruby-lang.org
<p><a href="https://benchmarksgame.alioth.debian.org/u64q/program.php?test=pidigits&lang=yarv&id=3" class="external">The benchmark program <code>pidigits.rb</code></a> runs faster if USE_GMP is disabled for divmod.</p>
<pre><code>$ time ./miniruby.orig pidigits.rb 10000 > /dev/null
real 0m5.932s
user 0m5.740s
sys 0m0.188s
</code></pre>
<pre><code>$ time ./miniruby.patched pidigits.rb 10000 > /dev/null
real 0m3.212s
user 0m3.056s
sys 0m0.152s
</code></pre>
<pre><code>diff --git a/bignum.c b/bignum.c
index 767659d..33a172e 100644
--- a/bignum.c
+++ b/bignum.c
@@ -2813,12 +2813,6 @@ rb_big_divrem_gmp(VALUE x, VALUE y)
static void
bary_divmod_branch(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
{
-#ifdef USE_GMP
- if (GMP_DIV_DIGITS < xn) {
- bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
- return;
- }
-#endif
bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
}
</code></pre>
<p>We can possibly tune performance.</p> Ruby master - Feature #11312 (Open): Add Resolv::DNS::Resource::IN::SPFhttps://bugs.ruby-lang.org/issues/113122015-06-26T18:58:49Zpostmodern (Hal Brodigan)postmodern.mod3@gmail.com
<p>The SPF type record (RFC4408 Section 3.1.1) is quite common now. The resolv library should probably support it. As a workaround I monkey patched in the resource class:</p>
<pre><code>class Resolv::DNS::Resource::IN::SPF < Resolv::DNS::Resource::IN::TXT
# resolv.rb doesn't define an SPF resource type.
TypeValue = 99
ClassValue = Resolv::DNS::Resource::IN::ClassValue
Resolv::DNS::Resource::ClassHash[[TypeValue, ClassValue]] = self
end
</code></pre>
<p>I could formalize my monkeypatch into an actual patch. I would just need to know whether SPF should be listed in the <code>ClassInsensitiveTypes</code> array.</p> Ruby master - Feature #10637 (Assigned): Puppet orchestration on vagrant fails with Error: Non-HT...https://bugs.ruby-lang.org/issues/106372014-12-23T18:59:56Zeshenayo (Eshe Pickett)eshe.pickett@gmail.com
<p>I encountered this issue while bringing up a VM using vagrant with virtualbox. I am using puppet to do some provisioning</p>
<p>==> default: Notice: Downloading from <a href="https://forge.puppetlabs.com" class="external">https://forge.puppetlabs.com</a> ...<br>
==> default: Error: Non-HTTP proxy URI: https://[proxy]:[port]/ class is: URI::HTTPS<br>
==> default: Error: Try 'puppet help module install' for usage<br>
==> default: Notice: Preparing to install into /etc/puppet/modules ...<br>
==> default: Notice: Downloading from <a href="https://forge.puppetlabs.com" class="external">https://forge.puppetlabs.com</a> ...<br>
==> default: Error: Non-HTTP proxy URI: https://[proxy]:[port]/ class is: URI::HTTPS<br>
==> default: Error: Try 'puppet help module install' for usage</p>
<p>I put in the print out to see what class in the above output</p>
<p>Puppet is using https to download modules, and it hits the open_http function</p>
<p>def OpenURI.open_http(buf, target, proxy, options) # :nodoc:<br>
if proxy<br>
proxy_uri, proxy_user, proxy_pass = proxy<br>
raise "Non-HTTP proxy URI: #{proxy_uri} class is: #{proxy_uri.class}" if proxy_uri.class != URI::HTTP<br>
end</p>
<p>I am new to ruby, so am unsure if this is the expected behavior. I have a work around, I set https_proxy to use the http_proxy, however, this is not by any means a permanent solution. Alternatively, I could change the ruby code to allow both HTTP and HTTPS URIs, please advise.</p> Ruby master - Feature #10459 (Assigned): [PATCH] rfc3339 method for Timehttps://bugs.ruby-lang.org/issues/104592014-10-30T11:12:16ZAntiarchitect (Andrey Voronkov)voronkovaa@gmail.com
<p>Alias for iso8601 method for compatibility with DateTime (Ruby on Rails).</p> Ruby master - Feature #10129 (Assigned): More descriptive error message for failed net/http requestshttps://bugs.ruby-lang.org/issues/101292014-08-13T22:34:43Zxshay (Xavier Shay)contact@xaviershay.com
<p>Hello,<br>
I would like to propose the following patch:</p>
<p>Before</p>
<pre><code>2.1.2 :003 > Net::HTTP.get(URI.parse("https://arsrtrtrstsrt.com/arstr"))
SocketError: getaddrinfo: nodename nor servname provided, or not known
</code></pre>
<p>After</p>
<pre><code>2.1.2 :003 > Net::HTTP.get(URI.parse("https://arsrtrtrstsrt.com/arstr"))
SocketError: Failed to open TCP connection to arsrtrtrstsrt.com:443 (getaddrinfo: nodename nor servname provided, or not known)
</code></pre>
<p>I have an implementation with test at <a href="https://github.com/ruby/ruby/pull/700" class="external">https://github.com/ruby/ruby/pull/700</a></p>
<p>Thank you for your consideration,<br>
Xavier</p> Ruby master - Bug #8445 (Assigned): IO.open and IO#set_enconding does not support :fallback optionhttps://bugs.ruby-lang.org/issues/84452013-05-24T22:03:00Zpjmtdw (Haruhiro Yoshimoto)pjmtdw@gmail.com
<p>RubyDoc says that <code>IO.open</code> and <code>IO#set_encoding</code> supports optional argument defined in <code>String#encode</code>.<br>
<a href="http://ruby-doc.org/core-2.0/IO.html#method-c-new-label-Options" class="external">http://ruby-doc.org/core-2.0/IO.html#method-c-new-label-Options</a><br>
In fact, <code>:invalid, :undef and :replace</code> works as expected.</p>
<p>However, <code>:fallback</code> option does not work neither for <code>IO.open</code> and <code>IO#set_encoding</code>.<br>
Following is the example code which does not work.<br>
<code>f(x)</code> is never called even if hoge.txt contains non convertible character.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s2">"./hoge.txt"</span><span class="p">,</span><span class="s2">"r:Shift_JIS:utf-8"</span><span class="p">,</span> <span class="ss">:fallback</span> <span class="o">=></span> <span class="nb">lambda</span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span><span class="n">f</span><span class="p">(</span><span class="n">x</span><span class="p">)}){</span><span class="o">|</span><span class="n">f</span><span class="o">|</span>
<span class="o">...</span>
<span class="p">}</span>
<span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s2">"./hoge.txt"</span><span class="p">){</span><span class="o">|</span><span class="n">f</span><span class="o">|</span>
<span class="n">f</span><span class="p">.</span><span class="nf">set_encoding</span><span class="p">(</span><span class="s2">"Shift_JIS"</span><span class="p">,</span><span class="s2">"utf-8"</span><span class="p">,</span><span class="ss">:fallback</span> <span class="o">=></span> <span class="nb">lambda</span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span><span class="n">f</span><span class="p">(</span><span class="n">x</span><span class="p">)})</span>
<span class="o">...</span>
<span class="p">}</span>
</code></pre>
<p>I Think this is because <code>fill_cbuf()</code> in <code>io.c</code> calls <code>rb_econv_convert()</code> from <code>transcode.c</code> directly.<br>
On the other hand, <code>fallback_func</code> is called in <code>transcode_loop()</code>, which is called by <code>str_encode()</code>.</p>
<p>Since <code>transcode_loop()</code> also calls <code>rb_econv_convert()</code>, I wrote a small patch which moves some codes from<br>
<code>transcode_loop()</code> to <code>rb_econv_convert()</code> to fix the problem.</p>
<p>The attached file is the patch. Hope this helps.</p> Ruby master - Feature #7412 (Assigned): Pathname#relative_path_from does not support mixed direct...https://bugs.ruby-lang.org/issues/74122012-11-20T20:15:24Z7er (Syver Enstad)syver.enstad@gmail.com
<p>=begin<br>
The support for mixing backslashes and forward slashes in the pathname module in the standard library seems to be broken on windows</p>
<pre><code>require 'pathname'
base = Pathname.new("c:\\")
filepath = Pathname.new("c:/foo/bar/file.ext")
base.relative_path_from(filepath)
</code></pre>
<p>raises <code>ArgumentError: different prefix: "c:\\" and "c:/foo/bar/file.ext"</code></p>
<p>Changing filepath to contain backslashes fixes the problem</p>
<pre><code>filepath = Pathname.new("c:\\foo\\bar\\file.ext")
base.relative_path_from(filepath)
</code></pre>
<p><code>=> #<Pathname:../../..></code><br>
=end</p> Ruby master - Feature #7362 (Assigned): Adding Pathname#start_with?https://bugs.ruby-lang.org/issues/73622012-11-15T22:38:40Zaef (Alexander E. Fischer)aef@raxys.net
<p>If a Pathname starts with another Pathname, that means that the former Pathname lies below the latter Pathname, as long as both Pathnames are interpreted from the same location or both are given as absolute.</p>
<p>Therefore I would like to see a method #start_with? just like the one on String but for Pathnames.</p>
<p>If you like the idea, just tell me. I will provide a patch then.</p> Ruby master - Feature #3608 (Assigned): Enhancing Pathname#each_child to be lazyhttps://bugs.ruby-lang.org/issues/36082010-07-24T10:27:14Ztaw (Tomasz Wegrzanowski)Tomasz.Wegrzanowski@gmail.com
<p>=begin<br>
Right now it lists entire directory, then yields<br>
every element, that is x.each_child(&b) means x.children.each(&b).</p>
<p>This is too slow for directories mounted over networked file systems etc.,<br>
and there is currently no way to get lazy behaviour, other than leaving<br>
convenient #each_child/#children API and moving to lower level.</p>
<p>With this patch:</p>
<ul>
<li>#children is eager like before, no change here</li>
<li>#each_child becomes lazy</li>
<li>#each_child without block returns lazy enumerator,<br>
so it can be used like this dir.each_child.find(&:symlink?)<br>
without losing laziness.</li>
</ul>
<p>Patch is against trunk. pathname.rb was in lib/ not ext/pathname/lib/<br>
before, but it works either way.</p>
<p>The part to return enumerator when called without a block wouldn't<br>
work in 1.8. If backport is desired, that line would need to be thrown<br>
away, and #children would need to build result array instead<br>
of calling each_child(with_directory).to_a - this would be straightforward.<br>
=end</p>