Ruby Issue Tracking System: Issueshttps://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112011-11-23T18:03:28ZRuby Issue Tracking System
Redmine Backport187 - Backport #5664 (Closed): Webrick broken FD_CLOEXEChttps://bugs.ruby-lang.org/issues/56642011-11-23T18:03:28Zcandlerb (Brian Candler)b.candler@pobox.com
<p>ruby-1.8.7-p352 $ grep -R CLOEXEC .<br>
./ext/fcntl/fcntl.c: * - FD_CLOEXEC - the value of the close-on-exec flag.<br>
./ext/fcntl/fcntl.c:#ifdef FD_CLOEXEC<br>
./ext/fcntl/fcntl.c: rb_define_const(mFcntl, "FD_CLOEXEC", INT2NUM(FD_CLOEXEC));<br>
./lib/drb/drb.rb: soc.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::FD_CLOEXEC<br>
./lib/drb/unix.rb: soc.fcntl(Fcntl::F_SETFL, Fcntl::FD_CLOEXEC) if defined? Fcntl::FD_CLOEXEC<br>
./lib/resolv.rb: sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD<br>
./lib/resolv.rb: sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD<br>
./lib/resolv.rb: sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD<br>
./lib/webrick/utils.rb: if defined?(Fcntl::FD_CLOEXEC)<br>
./lib/webrick/utils.rb: io.fcntl(Fcntl::FD_CLOEXEC, 1)</p>
<p>There you can see lots of examples of FD_CLOEXEC being used correctly: fcntl (command F_SETFD, value FD_CLOEXEC)</p>
<p>But in the last line, Webrick is calling fcntl wrongly: it is calling command FD_CLOEXEC with value 1 !! So what it's actually calling is command F_GETFD, which does nothing.</p>
<blockquote>
<blockquote>
<p>Fcntl.constants.select { |x| Fcntl.const_get(x) == Fcntl::FD_CLOEXEC }<br>
=> ["F_GETFD", "FD_CLOEXEC", "O_WRONLY", "F_RDLCK"]</p>
</blockquote>
</blockquote>
<p>I have checked this in the latest 1.8.7-p352 source too, and it's the same there.</p> Ruby master - Feature #4645 (Feedback): Pass existing buffer to getsockopthttps://bugs.ruby-lang.org/issues/46452011-05-04T18:11:19Zcandlerb (Brian Candler)b.candler@pobox.com
<p>There are cases when you need to pass a pre-initialized buffer to<br>
getsockopt, but ruby currently doesn't support this.</p>
<p>For an example, see the API used by iptables to manipulate the firewall<br>
rulesets (below). You have to set the table name in the buffer passed to<br>
getsockopt; the call then modifies the remainder of the buffer.</p>
<p>So I propose that BasicSocket#getsockopt be enhanced to allow an optional<br>
third parameter, which is an existing String buffer, used both to pass<br>
data and receive the result.</p>
<p>Does this sound reasonable?</p>
<p>Regards, Brian.</p>
<p>-------- 8< ----------------------------------------------<br>
/* extract from iptables-1.4.4/libiptc/libiptc.c */</p>
<p>struct xtc_handle *<br>
TC_INIT(const char *tablename)<br>
{<br>
STRUCT_GETINFO info;<br>
socklen_t s;<br>
int sockfd;<br>
...<br>
s = sizeof(info);</p>
<pre><code> strcpy(info.name, tablename);
if (getsockopt(sockfd, TC_IPPROTO, SO_GET_INFO, &info, &s) < 0) {
close(sockfd);
return NULL;
}
DEBUGP("valid_hooks=0x%08x, num_entries=%u, size=%u\n",
info.valid_hooks, info.num_entries, info.size);
</code></pre>
<p>...</p> Ruby 1.8 - Bug #4496 (Rejected): ri can't describe Kernel.warnhttps://bugs.ruby-lang.org/issues/44962011-03-12T19:11:12Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
It appears to be impossible to read documentation on Kernel.warn, due to overlapping matches.</p>
<p>$ ruby -v<br>
ruby 1.8.7 (2010-06-23 patchlevel 299) [x86_64-linux]<br>
$ ri 'Kernel.warn' | cat<br>
More than one method matched your request. You can refine<br>
your search by asking for information on one of:</p>
<pre><code> Kernel#warn, Kernel#with_warnings, Kernel#enable_warnings,
Kernel#silence_warnings, Kernel#suppress_warnings, Kernel#warn
</code></pre>
<p>$ ri 'Kernel#warn' | cat<br>
More than one method matched your request. You can refine<br>
your search by asking for information on one of:</p>
<pre><code> Kernel#warn, Kernel#with_warnings, Kernel#enable_warnings,
Kernel#silence_warnings, Kernel#suppress_warnings, Kernel#warn
</code></pre>
<p>$ ri 'Kernel::warn' | cat<br>
Nothing known about Kernel::warn</p>
<p>Suggested solution: if your search term is an exact match, then display it (don't search for other possible matches)</p>
<p>=end</p> Ruby master - Bug #3718 (Closed): [doc] ri doesn't document Object#<=>https://bugs.ruby-lang.org/issues/37182010-08-19T18:07:28Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
1.9.2 apparently implements Object#<=> (or Kernel#<=> ?)</p>
<p>$ irb192 --simple-prompt</p>
<blockquote>
<blockquote>
<p>Object.new <=> Object.new<br>
=> nil</p>
</blockquote>
</blockquote>
<p>But ri doesn't seem to know about it:</p>
<p>$ ri192 '<=>'<br>
Nothing known about <=><br>
$ ri192 'Object#<=>'<br>
Nothing known about Object#<=><br>
$ ri192 'Kernel#<=>'<br>
Nothing known about Kernel#<=></p>
<p>(However, I note that ri192 'String#<=>' does work as expected)<br>
=end</p> Backport187 - Backport #3200 (Closed): String#gsub! doesn't error on frozen stringhttps://bugs.ruby-lang.org/issues/32002010-04-25T18:26:11Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
gsub! does not raise an error on a frozen string unless a change is actually made. e.g.</p>
<blockquote>
<blockquote>
<p>s = "a".freeze<br>
=> "a"<br>
s.gsub!(/b/,'')<br>
=> nil</p>
</blockquote>
</blockquote>
<p>But this is inconsistent with other mutating methods on frozen strings, e.g.</p>
<blockquote>
<blockquote>
<p>s.squeeze!<br>
TypeError: can't modify frozen string<br>
from (irb):3:in <code>squeeze!' from (irb):3 from :0 s.tr!('b','c') TypeError: can't modify frozen string from (irb):4:in </code>tr!'<br>
from (irb):4<br>
from :0</p>
</blockquote>
</blockquote>
<p>Not sure if this unexpected behaviour is "bug" or "feature". The ri documentation of String#gsub! doesn't mention this anomaly.</p>
<p>Tested with ruby 1.8.7 (2009-06-12 patchlevel 174) [x86_64-linux] from Ubuntu Karmic<br>
=end</p> Backport187 - Backport #3106 (Closed): Out-of-bounds on fd_sethttps://bugs.ruby-lang.org/issues/31062010-04-07T18:02:06Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
Ruby uses select() to switch between active file descriptors, and has three fd_set's in struct thread_status_t. However, as far as I can see, no bounds checking is done to see if these are exceeded. Therefore, if you have more than FDSETSIZE files open, ruby can write beyond bounds and strange things happen.</p>
<p>Many Linux systems have FDSETSIZE 1024 and ulimit -n 1024 by default, and so the problem doesn't arise, but the ulimit can be raised by the sysadmin. At this point, ruby is happy to open more than 1024 files, and then crashes.</p>
<p>Should ruby not check for FDSETSIZE and refuse to use files whose fds are beyond this? (This limitation could be removed later if ruby ever moved to poll/epoll/kpoll)</p>
<p>The following code demonstrates the problem. It uses 'connect', because this causes ruby to do a non-blocking connect followed by a select.</p>
<p>require 'socket'<br>
srv = []<br>
cli = []<br>
1024.times do<br>
s = TCPServer.new('127.0.0.1',nil)<br>
puts s.fileno<br>
c = TCPSocket.new('127.0.0.1',s.addr[1])<br>
puts c.fileno<br>
srv << s<br>
cli << c<br>
end</p>
<p>Given 'ulimit -n 2048', for me it falls over like this:</p>
<p>...<br>
1213<br>
1214<br>
1215<br>
ert.rb:7:in <code>initialize': Socket operation on non-socket - connect(2) (Errno::ENOTSOCK) from ert.rb:7:in </code>new'<br>
from ert.rb:7<br>
from ert.rb:4:in `times'<br>
from ert.rb:4</p>
<p>More discussion at <a href="http://www.ruby-forum.com/topic/207462" class="external">http://www.ruby-forum.com/topic/207462</a><br>
=end</p> Backport187 - Backport #2946 (Closed): Apparently inconsistent zip of Rangehttps://bugs.ruby-lang.org/issues/29462010-03-08T22:30:00Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
You can zip an Array onto a Range, but not a Range onto an Array.</p>
<blockquote>
<blockquote>
<p>RUBY_DESCRIPTION<br>
=> "ruby 1.8.7 (2009-06-12 patchlevel 174) [x86_64-linux]"</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p>(9..12).zip([1,2,3,4])<br>
=> [[9, 1], [10, 2], [11, 3], [12, 4]]</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p>[1,2,3,4].zip(5..8)<br>
TypeError: can't convert Range into Array<br>
from (irb):6:in `zip'<br>
from (irb):6<br>
from :0</p>
</blockquote>
</blockquote>
<p>Wonder if zip should call #to_a on its argument?</p>
<blockquote>
<blockquote>
<p>(5..8).to_a<br>
=> [5, 6, 7, 8]<br>
=end</p>
</blockquote>
</blockquote> Ruby master - Bug #2545 (Closed): Array#delete_if is borked if user calls 'break'https://bugs.ruby-lang.org/issues/25452010-01-02T05:54:53Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
Array is corrupted if you break out of a delete_if { ... } loop. I would expect that the elements already marked as deleted would be deleted, and the remainder of the array would be unchanged.</p>
<blockquote>
<blockquote>
<p>a = [5,6,7,8,9,10]<br>
=> [5, 6, 7, 8, 9, 10]<br>
a.delete_if { |x| break if x > 8; x < 7 }<br>
=> nil<br>
a<br>
=> [7, 8, 7, 8, 9, 10]</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p>RUBY_VERSION<br>
=> "1.8.7"<br>
RUBY_PATCHLEVEL<br>
=> 174<br>
=end</p>
</blockquote>
</blockquote> Ruby master - Bug #1926 (Rejected): Different eval/binding behaviour in 1.9https://bugs.ruby-lang.org/issues/19262009-08-11T23:00:13Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
In 1.8.6, you can set a local variable in a binding using eval. This doesn't seem to work in 1.9.2-preview1.</p>
<p>def define_a(b)<br>
eval "a=1", b<br>
end</p>
<p>define_a(binding)<br>
puts local_variables.inspect</p>
<a name="18-prints-a"></a>
<h1 >1.8: prints ["a"]<a href="#18-prints-a" class="wiki-anchor">¶</a></h1>
<a name="19-prints-"></a>
<h1 >1.9: prints []<a href="#19-prints-" class="wiki-anchor">¶</a></h1>
<p>Similarly:</p>
<p>def another_a(&blk)<br>
eval "a=1", blk.binding<br>
yield<br>
end</p>
<p>another_a do<br>
puts local_variables.inspect<br>
end</p>
<a name="18-prints-a-2"></a>
<h1 >1.8: prints ["a"]<a href="#18-prints-a-2" class="wiki-anchor">¶</a></h1>
<a name="19-prints--2"></a>
<h1 >1.9: prints []<a href="#19-prints--2" class="wiki-anchor">¶</a></h1>
<p>=end</p> Ruby master - Feature #1900 (Closed): Suggestion: Encoding#ascii_compatible?https://bugs.ruby-lang.org/issues/19002009-08-06T23:23:31Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
An important property of an Encoding is whether it is ASCII-compatible. However as far as I can see, you can only test for this indirectly, e.g.</p>
<p>Encoding.compatible?("a".force_encoding("ISO-8859-1"), "a".force_encoding("US-ASCII"))</p>
<p>So I suggest exposing rb_enc_asciicompat as a property of the Encoding objects themselves.<br>
=end</p> Ruby master - Bug #1853 (Rejected): Cannot make constants using upper-case extended characters?https://bugs.ruby-lang.org/issues/18532009-08-01T17:00:39Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin</p>
<blockquote>
<blockquote>
<p>SCHÖN = 1 # constant<br>
=> 1<br>
ÜBER = 2 # local variable!<br>
=> 2<br>
self.class.constants.grep(/SCH|BER/)<br>
=> [:SCHÖN]<br>
local_variables.grep(/SCH|BER/)<br>
=> [:ÜBER]</p>
</blockquote>
</blockquote>
<p>I am not sure from the source code whether this is intentional or not.<br>
In parse.c it uses rb_enc_isupper which understands encodings:</p>
<pre><code> else if (rb_enc_isupper(m[0], enc)) {
id = ID_CONST;
}
else {
id = ID_LOCAL;
</code></pre>
<p>This is in rb_intern3. And yet it is called from rb_intern2 which says:</p>
<p>ID<br>
rb_intern2(const char *name, long len)<br>
{<br>
return rb_intern3(name, len, rb_usascii_encoding());<br>
}</p>
<p>If this is intentional, it seems like an arbitrary restriction. Unicode characters are unambiguously classified into upper-case, lower-case and neither. If they can be used anywhere within an identifier, why not at the start of a constant?<br>
=end</p> Ruby master - Bug #1843 (Closed): Symbol#inspect raises exceptionhttps://bugs.ruby-lang.org/issues/18432009-07-31T02:22:36Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
If you can create an object, I think you should always be able to inspect it.</p>
<p>However Symbol#inspect raises an exception if it was made from a string with an invalid encoding.</p>
<blockquote>
<blockquote>
<p>"hello\xff".to_sym.inspect<br>
ArgumentError: invalid byte sequence in UTF-8<br>
from (irb):26:in <code>inspect' from (irb):26 from /usr/local/bin/irb19:12:in </code>'</p>
</blockquote>
</blockquote>
<p>Note that the to_sym is quite happy; it's the inspect which fails.</p>
<blockquote>
<blockquote>
<p>"hello\xff".to_sym; nil<br>
=> nil</p>
</blockquote>
</blockquote>
<p>This means you cannot handle such objects in irb.</p>
<blockquote>
<blockquote>
<p>s = :"hello\xff"<br>
ArgumentError: invalid byte sequence in UTF-8<br>
from /usr/local/lib/ruby/1.9.1/irb/inspector.rb:84:in <code>inspect' from /usr/local/lib/ruby/1.9.1/irb/inspector.rb:84:in </code>block in <a href="module:IRB" class="external">module:IRB</a>'<br>
from /usr/local/lib/ruby/1.9.1/irb/inspector.rb:30:in <code>call' from /usr/local/lib/ruby/1.9.1/irb/inspector.rb:30:in </code>inspect_value'<br>
from /usr/local/lib/ruby/1.9.1/irb/context.rb:259:in <code>inspect_last_value' from /usr/local/lib/ruby/1.9.1/irb.rb:301:in </code>output_value'<br>
from /usr/local/lib/ruby/1.9.1/irb.rb:150:in <code>block (2 levels) in eval_input' from /usr/local/lib/ruby/1.9.1/irb.rb:263:in </code>signal_status'<br>
from /usr/local/lib/ruby/1.9.1/irb.rb:146:in <code>block in eval_input' from /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:244:in </code>block (2 levels) in each_top_level_statement'<br>
from /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:230:in <code>loop' from /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:230:in </code>block in each_top_level_statement'<br>
from /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in <code>catch' from /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in </code>each_top_level_statement'<br>
from /usr/local/lib/ruby/1.9.1/irb.rb:145:in <code>eval_input' from /usr/local/lib/ruby/1.9.1/irb.rb:69:in </code>block in start'<br>
from /usr/local/lib/ruby/1.9.1/irb.rb:68:in <code>catch' from /usr/local/lib/ruby/1.9.1/irb.rb:68:in </code>start'<br>
from /usr/local/bin/irb19:12:in `'Maybe IRB bug!!</p>
</blockquote>
</blockquote>
<p>=end</p> Ruby master - Bug #1839 (Closed): String#tr borked for UTF-8 0080..00FFhttps://bugs.ruby-lang.org/issues/18392009-07-30T18:44:01Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin</p>
<blockquote>
<blockquote>
<p>a = "uber"<br>
=> "uber"<br>
a.encoding<br>
=> #<a href="Encoding:UTF-8" class="external">Encoding:UTF-8</a><br>
b = a.tr("u","ü")<br>
=> "\xFCber"<br>
b.encoding<br>
=> #<a href="Encoding:UTF-8" class="external">Encoding:UTF-8</a></p>
</blockquote>
</blockquote>
<p>What's more remarkable,</p>
<blockquote>
<blockquote>
<p>b.valid_encoding?<br>
=> true</p>
</blockquote>
</blockquote>
<p>!!!</p>
<blockquote>
<blockquote>
<p>b << "x"<br>
=> "\xFCberx"<br>
b.valid_encoding?<br>
=> true</p>
</blockquote>
</blockquote>
<p>!!!</p>
<p>And yet it works for codepoints > 255:</p>
<blockquote>
<blockquote>
<p>c = a.tr("u","ł")<br>
=> "łber"<br>
c.encoding<br>
=> #<a href="Encoding:UTF-8" class="external">Encoding:UTF-8</a></p>
</blockquote>
</blockquote>
<p>=end</p> Ruby master - Bug #1836 (Closed): Can change encoding on frozen Stringhttps://bugs.ruby-lang.org/issues/18362009-07-30T17:05:59Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
String#encode! lets you change the encoding on a frozen String, as long as the character sequence is unchanged by the operation.</p>
<blockquote>
<blockquote>
<p>s = "hello"<br>
=> "hello"<br>
s.freeze<br>
=> "hello"<br>
s.encode!("ISO-8859-1")<br>
=> "hello"<br>
s.encoding<br>
=> #<a href="Encoding:ISO-8859-1" class="external">Encoding:ISO-8859-1</a></p>
</blockquote>
</blockquote>
<p>=end</p> Ruby master - Feature #1832 (Closed): irb -whttps://bugs.ruby-lang.org/issues/18322009-07-29T16:48:27Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
It would be nice if either irb had a -w flag, or $VERBOSE defaulted to true in irb.</p>
<p>$ irb19<br>
irb(main):001:0> $VERBOSE<br>
=> false<br>
=end</p> Ruby master - Feature #1831 (Closed): Suggestion: warn on repeated character in character classhttps://bugs.ruby-lang.org/issues/18312009-07-29T16:45:10Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
Suggestion: warn if the same character appears more than once in a character class (or more restrictedly: if the character ':' appears both at the start and end of a character class)</p>
<p>This is to give some indication of the problem if you do the following:</p>
<blockquote>
<blockquote>
<p>RUBY_DESCRIPTION<br>
=> "ruby 1.9.2dev (2009-07-18 trunk 24186) [i686-linux]"<br>
$WARN=true<br>
=> true<br>
"uber" =~ /[:lower:]/<br>
=> 2<br>
=end</p>
</blockquote>
</blockquote> Ruby master - Bug #1386 (Rejected): Spurious class "ARGF.class" in ObjectSpacehttps://bugs.ruby-lang.org/issues/13862009-04-17T18:42:33Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
$ ruby19 -e 'ObjectSpace.each_object(Class) { |c| puts c if c.to_s =~ /./ }'<br>
ARGF.class</p>
<p>However this 'class' is not accessible by name:</p>
<p>$ ruby19 -e 'puts Object.const_get("ARGF.class")'<br>
-e:1:in <code>const_get': wrong constant name ARGF.class (NameError) from -e:1:in </code>'<br>
=end</p> Backport186 - Backport #1284 (Closed): Net::HTTP POST performancehttps://bugs.ruby-lang.org/issues/12842009-03-13T17:23:55Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
Net::HTTP uses a fixed block size of 1024 bytes when streaming or chunking POST bodies, which leads to very poor performance for large file uploads.</p>
<p>Issue affects both trunk and branches/ruby_1_8</p>
<p>The attached tiny patch changes this to a tunable constant (BUFSIZE) with a default of 16K.</p>
<p>Notes:</p>
<ul>
<li>A similar change has already been made to net/protocol.rb in r12092</li>
<li>WEBrick httprequest and httpresponse already have a BUFSIZE constant</li>
<li>WEBrick was made even more tunable in r10167 (trunk only)<br>
=end</li>
</ul> Ruby 1.8 - Bug #1252 (Closed): [PATCH] Net::Telnet FailEOFhttps://bugs.ruby-lang.org/issues/12522009-03-08T02:58:38Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
A local override of the FailEOF flag wasn't propagating from cmd() to waitfor(). Patch attached.<br>
=end</p> Backport186 - Backport #1173 (Closed): Method name typo in soap/mimemessage.rbhttps://bugs.ruby-lang.org/issues/11732009-02-18T23:58:34Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
Looks like nobody has ever used this functionality - the typo still exists even at tip of 1.8 branch :-)</p>
<p>--- lib/soap/mimemessage.rb.orig 2009-02-18 14:34:00.000000000 +0000<br>
+++ lib/soap/mimemessage.rb 2009-02-18 14:38:28.000000000 +0000<br>
@@ -233,7 +233,7 @@<br>
end</p>
<pre><code>def to_s
</code></pre>
<ul>
<li>str = headers_str + "\r\n\r\n" + conent_str</li>
</ul>
<ul>
<li>str = headers_str + "\r\n\r\n" + content_str<br>
end<br>
end<br>
=end</li>
</ul> Ruby master - Feature #855 (Closed): HTTP/1.1 fixes and other enhancements to webrickhttps://bugs.ruby-lang.org/issues/8552008-12-11T19:08:04Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
I raised the following issues on ruby-core:</p>
<ol>
<li>
<p>When returning an open IO object (without Content-Length or chunking), Webrick fails to close the HTTP/1.1 connection, and hence the client waits forever for the end of the data.<br>
<a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/18454" class="external">http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/18454</a><br>
<a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/18565" class="external">http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/18565</a></p>
</li>
<li>
<p>Webrick makes it very difficult to send a '100 continue' response when a HTTP/1.1 client requests one, and yet the RFC2616 says it <em>must</em> do so.<br>
<a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/18459" class="external">http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/18459</a></p>
</li>
<li>
<p>It would be convenient to be able to stream not just real IO objects, but other objects which duck-type like them (such as an open zip file entry from rubyzip)<br>
<a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/18460" class="external">http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/18460</a></p>
</li>
<li>
<p>It would be convenient to be able to provide a proc object to generate a streamed response:<br>
proc { |out| out << "data"; out << "more data"; etc }</p>
</li>
<li>
<p>The default block size of 4K is too small to be efficient when serving large files. This was already fixed for 1.9 in<br>
<a href="http://redmine.ruby-lang.org/repositories/revision/ruby-19?rev=10167" class="external">http://redmine.ruby-lang.org/repositories/revision/ruby-19?rev=10167</a><br>
(default now 64K and tunable). Please consider this for 1.8, especially since a similar improvement has been backported for Net::HTTP in<br>
<a href="http://redmine.ruby-lang.org/repositories/revision/ruby-18?rev=12092" class="external">http://redmine.ruby-lang.org/repositories/revision/ruby-18?rev=12092</a></p>
</li>
</ol>
<p>The attached file contains small monkey-patches to address these issues. If there is interest these could be rewritten as actual patches against webrick.<br>
=end</p> Ruby 1.8 - Bug #720 (Closed): [patch] autoconf changes needed for uClibc stdiohttps://bugs.ruby-lang.org/issues/7202008-11-08T05:15:49Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
[Migrated from http://rubyforge.org/tracker/index.php?func=detail&aid=15677&group_id=426&atid=1698]</p>
<p>ruby doesn't work properly under uClibc without a patch. This is because uClibc uses __bufpos and __bufread (rather<br>
than bufpos and bufread), which configure.in isn't currently detecting. The most immediate symptom is that an exception<br>
is raised if you try to read from a UDP socket:</p>
<p>root@OpenWrt:~# irb<br>
irb(main):001:0> require 'socket'<br>
=> true<br>
irb(main):002:0> s = UDPSocket.new<br>
=> #<a href="UDPSocket:0x444000" class="external">UDPSocket:0x444000</a><br>
irb(main):003:0> s.bind("0.0.0.0",1234)<br>
=> 0<br>
irb(main):004:0> d = s.recvfrom(512)<br>
IOError: recv for buffered IO<br>
from (irb):4:in `recvfrom'<br>
from (irb):4<br>
irb(main):005:0></p>
<p>[Tested using OpenWrt, an embedded Linux distro which uses uClibc]</p>
<p>The simple fix is attached.</p>
<p>Previously posted to ruby-core for comment, but no response forthcoming.<br>
<a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/12020" class="external">http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/12020</a><br>
<a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/13262" class="external">http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/13262</a><br>
=end</p> Ruby master - Feature #709 (Rejected): Enumerator#+https://bugs.ruby-lang.org/issues/7092008-11-03T19:02:42Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
Enumerators could be directly composable:</p>
<p>class Enumerator<br>
def +(other)<br>
Enumerator.new do |y|<br>
each { |e| y << e }<br>
other.each { |e| y << e }<br>
end<br>
end<br>
end</p>
<p>if <strong>FILE</strong> == $0<br>
a = (1..3).to_enum + (10..12).to_enum + (17..20).to_enum<br>
a.each { |i| puts i }<br>
end</p>
<p>The only problem I can see here is that this might open the floodgates to requests for more methods such as & and |, and it's not clear how those would behave. (Personally I'd go for a merge which compares the head items from each of the operands, which assumes that the operands are already in sorted order, but others may disagree)<br>
=end</p> Ruby master - Feature #708 (Rejected): Lazy Enumerator#select, Enumerator#map etc.https://bugs.ruby-lang.org/issues/7082008-11-03T18:54:26Zcandlerb (Brian Candler)b.candler@pobox.com
<p>There are a number of methods in <code>Enumerable</code> that build an <code>Array</code> of results from the entire collection: <code>map</code>, <code>select</code>, <code>take</code>, etc.</p>
<p>I propose that the <code>Enumerator</code> class have its own implementations of these methods, which return another <code>Enumerator</code>. Enumerators can then be chained:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">seq</span><span class="p">.</span><span class="nf">to_enum</span><span class="p">.</span><span class="nf">map</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}.</span><span class="nf">select</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}.</span><span class="nf">take</span><span class="p">(</span><span class="o">...</span><span class="p">).</span><span class="nf">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">x</span> <span class="p">}</span>
</code></pre>
<p>This runs horizontally, that is, each element is processed left to right. No intermediate arrays are created, and it works happily with sequences of arbitrary length.</p>
<p>There are precendents for <code>SomeClass#select</code> behaving differently to <code>Enumerable#select</code>. For example, <code>Hash#select</code> returns a <code>Hash</code>. So I believe it would be reasonable for <code>Enumerator</code> to return another <code>Enumerator</code>.</p>
<p>You can then choose between array-building or lazy evaluation, depending on whether there is an Enumerator in the chain. Of course, the last Enumerator has to be turned into something useful, e.g. by calling <code>to_a</code> or <code>each { ... }</code>.</p>
<p>Normal</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">res</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="mi">1_000_000</span><span class="p">).</span><span class="nf">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span> <span class="o">*</span> <span class="mi">2</span> <span class="p">}.</span><span class="nf">take</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
</code></pre>
<p>Lazy</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">res</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="mi">1_000_000</span><span class="p">).</span><span class="nf">to_enum</span><span class="p">.</span><span class="nf">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span> <span class="o">*</span> <span class="mi">2</span> <span class="p">}.</span><span class="nf">take</span><span class="p">(</span><span class="mi">100</span><span class="p">).</span><span class="nf">to_a</span>
</code></pre>
<p>I have attached a simple implementation of this for <code>select</code>, <code>map</code>, <code>take</code> and a new method <code>skip</code>. There are further methods like <code>take_while</code>, <code>zip</code> and so on which would also need to be implemented.</p> Ruby master - Feature #707 (Closed): Documentation for Enumerator chaininghttps://bugs.ruby-lang.org/issues/7072008-11-03T18:41:44Zcandlerb (Brian Candler)b.candler@pobox.com
<p>=begin<br>
Enumerators now support a horizontal filter/chaining pattern:</p>
<p>generator.filter1 { ... }.filter2 { ... }.filter3 { ... }.consumer</p>
<p>The overall pattern for a filter is:</p>
<p>Enumerator.new do |y|<br>
source.each do |input| # filter INPUT<br>
...<br>
y << output # filter OUTPUT<br>
end<br>
end</p>
<p>This is extremely powerful. However it is not obvious to the newcomer that this is even possible. (Confusion may arise where people know Ruby 1.8's Enumerator, which cannot do this)</p>
<p>So I would just like to see this pattern documented with an example, e.g. under ri Enumerator.new</p>
<p>I have attached a possible example. Note that I have written my Fib generator in a style familiar from ruby-1.8, to emphasise that the Enumerator filter doesn't require a specially-written generator.<br>
=end</p>