https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112010-01-21T00:35:19ZRuby Issue Tracking SystemRuby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77272010-01-21T00:35:19Zhongli (Hongli Lai)hongli@phusion.nl
<ul><li><strong>File</strong> <a href="/attachments/811">0001-Add-method-Process.fork_supported-for-checking-wheth.patch</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/811/0001-Add-method-Process.fork_supported-for-checking-wheth.patch">0001-Add-method-Process.fork_supported-for-checking-wheth.patch</a> added</li></ul><p>=begin<br>
Oops, I attached the wrong patch: the first one contains some local changes which I did not intend to include. Here's the correct patch.<br>
=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77312010-01-21T08:51:11Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Rejected</i></li></ul><p>=begin<br>
use defined?(fork) instead.<br>
=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77332010-01-21T09:33:16Zluislavena (Luis Lavena)luislavena@gmail.com
<ul></ul><p>=begin<br>
Hmn, defined?(fork) is not very useful:</p>
<pre><code>
C:\Users\Luis>pik ruby -e "puts defined?(fork)"
IronRuby 0.9.3.0 on .NET 2.0.0.0
nil
jruby 1.4.0 (ruby 1.8.7 patchlevel 174) (2009-11-02 69fbfa3) (Java HotSpot(TM) Client VM 1.6.0_17) [x86-java]
method
ruby 1.8.6 (2009-06-08 patchlevel 369) [i386-mswin32]
method
ruby 1.8.6 (2009-08-04 patchlevel 383) [i386-mingw32]
method
ruby 1.8.7 (2009-12-24 patchlevel 248) [i386-mingw32]
method
ruby 1.8.7 (2009-12-24 patchlevel 248) [i386-mswin32]
method
ruby 1.9.1p376 (2009-12-07 revision 26041) [i386-mingw32]
method
ruby 1.9.1p376 (2009-12-07 revision 26041) [i386-mswin32]
method
ruby 1.9.2dev (2010-01-02 trunk 26229) [i386-mingw32]
</code></pre>
<p>Yes, 1.9.2 returns nothing, not even nil</p>
<p>That means that checking for fork definition on any version as condition will make that code execute.</p>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77342010-01-21T13:13:01Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>=begin<br>
Hi,</p>
<p>At Thu, 21 Jan 2010 09:36:33 +0900,<br>
Luis Lavena wrote in <a href="https://blade.ruby-lang.org/ruby-core/27643">[ruby-core:27643]</a>:</p>
<blockquote>
<p>C:\Users\Luis>pik ruby -e "puts defined?(fork)"<br>
ruby 1.9.2dev (2010-01-02 trunk 26229) [i386-mingw32]<br>
</p>
<p>Yes, 1.9.2 returns nothing, not even nil</p>
</blockquote>
<p>In 1.9, #puts no longer deals with nil specially. Try p.</p>
<blockquote>
<p>That means that checking for fork definition on any version<br>
as condition will make that code execute.</p>
</blockquote>
<p>Anyway, neither can help you in older versions.</p>
<p>--<br>
Nobu Nakada</p>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77352010-01-21T13:17:37Zluislavena (Luis Lavena)luislavena@gmail.com
<ul></ul><p>=begin<br>
Yikes, not even the old puts can save or be consistent anymore :-P</p>
<p>Thank you Nobu for enlighten me.</p>
<p>--<br>
Luis Lavena</p>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77372010-01-21T18:44:54Zhongli (Hongli Lai)hongli@phusion.nl
<ul></ul><p>=begin<br>
#fork is defined in all versions of MRI on all platforms, even on platforms where it's not supported. It's just that calling #fork will raise NotImplementedError. Consider this snippet from process.c:</p>
<p>#if defined(HAVE_FORK) && !defined(CANNOT_FORK_WITH_PTHREAD)<br>
...<br>
static VALUE<br>
rb_f_fork(VALUE obj)<br>
{<br>
...fork code here...<br>
}<br>
#else<br>
#define rb_f_fork rb_f_notimplement<br>
#endif</p>
<p>...</p>
<p>void<br>
Init_process(void)<br>
{<br>
rb_define_virtual_variable("$?", rb_last_status_get, 0);<br>
rb_define_virtual_variable("$$", get_pid, 0);<br>
rb_define_global_function("exec", rb_f_exec, -1);<br>
rb_define_global_function("fork", rb_f_fork, 0);</p>
<p>As you can see there's no #ifdef around rb_define_global_function("fork", ...).</p>
<p>I want to have a way to check whether rb_f_fork is implemented, without calling it and catching NotImplementedError.<br>
=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77382010-01-21T18:56:30Zhongli (Hongli Lai)hongli@phusion.nl
<ul></ul><p>=begin<br>
Tanaka Akira said that respond_to? returns false for methods that are not implemented since 1.9.2. I did not know that, but this solves my issue. This can be closed now.<br>
=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77392010-01-21T20:06:58Zvvs (Vladimir Sizikov)vsizikov@gmail.com
<ul></ul><p>=begin<br>
On Thu, Jan 21, 2010 at 11:03 AM, Hongli Lai <a href="mailto:hongli@plan99.net" class="email">hongli@plan99.net</a> wrote:</p>
<blockquote>
<p>On 1/21/10 10:53 AM, Tanaka Akira wrote:</p>
<blockquote>
<p>respond_to? returns false for methods which is not implemented since 1.9.2.</p>
<p>See NEWS.</p>
</blockquote>
<p>Ah, that is good news. :) You can close my issue then, sorry for the confusion.</p>
</blockquote>
<p>Whoa! This is rather unexpected. And seems to be only adding to the confusion.<br>
Other Ruby impls might not behave like this, not to mention that this<br>
change of respond_to?<br>
behavior only affects built-in methods. For regular methods, it won't work.</p>
<p>So, we end up with situation that for some non-implemented methods<br>
respond_to? would return true,<br>
for some other it would return false.</p>
<p>Thanks,<br>
--Vladimir</p>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77462010-01-22T03:49:54Zvvs (Vladimir Sizikov)vsizikov@gmail.com
<ul></ul><p>=begin<br>
On Thu, Jan 21, 2010 at 10:53 AM, Tanaka Akira <a href="mailto:akr@fsij.org" class="email">akr@fsij.org</a> wrote:</p>
<blockquote>
<p>2010/1/21 Hongli Lai <a href="mailto:hongli@plan99.net" class="email">hongli@plan99.net</a>:</p>
<blockquote>
<p>This always returns true even on platforms where fork is not actually supported. See<br>
my Redmine reply.</p>
</blockquote>
<p>respond_to? returns false for methods which is not implemented since 1.9.2.</p>
</blockquote>
<p>I should probably also add that this is close to impossible to<br>
implement on JRuby (and I assume on IronRuby too, and maybe some<br>
others). In case of JRuby, we build once and then the resulting<br>
product can be used on various platforms, so those platform specific<br>
things are queried at runtime. In some cases we just invoke a native<br>
functions via FFI at runtime and only then would see<br>
NotImplementedError out of those calls. So, basically, untill the<br>
method is executed, we can't really know whether it is supported or<br>
not on some platforms.</p>
<p>So, this new behavior is not "portable" in a sense that it won't work<br>
on all 1.9.2-compatible implementations, which would only add to<br>
confusion.</p>
<p>Thanks,<br>
--Vladimir</p>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77482010-01-22T04:09:53Zheadius (Charles Nutter)headius@headius.com
<ul></ul><p>=begin<br>
On Thu, Jan 21, 2010 at 12:49 PM, Vladimir Sizikov <a href="mailto:vsizikov@gmail.com" class="email">vsizikov@gmail.com</a> wrote:</p>
<blockquote>
<p>I should probably also add that this is close to impossible to<br>
implement on JRuby (and I assume on IronRuby too, and maybe some<br>
others). In case of JRuby, we build once and then the resulting<br>
product can be used on various platforms, so those platform specific<br>
things are queried at runtime. In some cases we just invoke a native<br>
functions via FFI at runtime and only then would see<br>
NotImplementedError out of those calls. So, basically, untill the<br>
method is executed, we can't really know whether it is supported or<br>
not on some platforms.</p>
<p>So, this new behavior is not "portable" in a sense that it won't work<br>
on all 1.9.2-compatible implementations, which would only add to<br>
confusion.</p>
</blockquote>
<p>I agree. Unless we dynamically go through all "potentially<br>
unimplemented" methods in the system and attach ahead-of-time tests to<br>
them, JRuby will not be able to support this. There is no<br>
system-specific compile time for JRuby, and as Vladimir mentions, we<br>
can't know what system we're going to run on until we start running.</p>
<p>It also seems very confusing to me that a method would show up in<br>
method lists, but respond_to? would produce false. I think this should<br>
always be true:</p>
<p>assert obj.respond_to? X if obj.methods.include X</p>
<p>For handling this fork case (and similar cases), there are other solutions:</p>
<ul>
<li>Hongli's suggested fork_supported?, though that pollutes some<br>
namespace for every such method we want to check</li>
<li>Just don't implement the method if it's not implemented. This<br>
doesn't help cases like in JRuby, where we may not know until runtime<br>
if we can support a method or not.</li>
<li>Provide another mechanism for querying specific features, like<br>
Platform.support? :fork</li>
</ul>
<p>As Ruby moves forward, it would be helpful if everyone remembered that<br>
MRI is not the only implementation anymore, and changes impact all the<br>
implementations in different ways.</p>
<ul>
<li>Charlie</li>
</ul>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77552010-01-22T12:39:19Zluislavena (Luis Lavena)luislavena@gmail.com
<ul></ul><p>=begin<br>
On Thu, Jan 21, 2010 at 9:57 PM, Hongli Lai <a href="mailto:hongli@plan99.net" class="email">hongli@plan99.net</a> wrote:</p>
<blockquote>
<p>[...]</p>
<blockquote>
<ul>
<li>Provide another mechanism for querying specific features, like<br>
Platform.support? :fork</li>
</ul>
</blockquote>
<p>How is this better than calling the method and catching NotImplementedError? Your<br>
check method, although returning a boolean, still calls the method under the hood.<br>
This makes #support? an expensive call which is something I wanted to avoid with<br>
#fork_supported?.</p>
</blockquote>
<p>I might be able to answer that.</p>
<p>While experimenting with Rubinius and MinGW, I've created a C library<br>
that collected at compile time the related information of the<br>
platform, and exposed it as CAPI extension.</p>
<p>That can, using extconf, #define, #ifdef etc the functionality exposed<br>
by the platform you're running on.</p>
<p>In the case of JRuby, that Platform module can evaluate the underlying<br>
OS capabilities and return you true/false without the need of<br>
triggering NotImplementedError</p>
<p>At the end, I believe both fork_supported? and Platform.support? :fork<br>
aim at the same, but the later can serve as API for other<br>
functionality, like symlink, hardlinks, etc.</p>
<p>Just a thought.</p>
<a name="PS-I-propose-we-paint-the-bike-shed-red"></a>
<h2 >PS: I propose we paint the bike shed red.<a href="#PS-I-propose-we-paint-the-bike-shed-red" class="wiki-anchor">¶</a></h2>
<h2>Luis Lavena<br>
AREA 17</h2>
<p>Perfection in design is achieved not when there is nothing more to add,<br>
but rather when there is nothing more to take away.<br>
Antoine de Saint-Exupéry</p>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77572010-01-22T14:27:54Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul></ul><p>=begin<br>
Hi,</p>
<p>In message "Re: <a href="https://blade.ruby-lang.org/ruby-core/27643">[ruby-core:27643]</a> [Feature <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Proposed method: Process.fork_supported? (Rejected)" href="https://redmine.ruby-lang.org/issues/2619">#2619</a>] Proposed method: Process.fork_supported?"<br>
on Thu, 21 Jan 2010 09:36:33 +0900, Luis Lavena <a href="mailto:redmine@ruby-lang.org" class="email">redmine@ruby-lang.org</a> writes:</p>
<p>|Hmn, defined?(fork) is not very useful:</p>
<p>We added a new behavior of defined?/respond_to? to 1.9 for exact same<br>
purpose in more generic way. We are not going to add redundant<br>
feature. If you want to stick with 1.8, JRuby, IronRuby or whatever,<br>
you have to persuade their maintainers.</p>
<pre><code> matz.
</code></pre>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77592010-01-22T17:27:19Zheadius (Charles Nutter)headius@headius.com
<ul></ul><p>=begin<br>
On Thu, Jan 21, 2010 at 9:43 PM, Tanaka Akira <a href="mailto:akr@fsij.org" class="email">akr@fsij.org</a> wrote:</p>
<blockquote>
<p>In general, I recommend programs call such methods simply and rescue<br>
NotImplementedError. This style should work with various Ruby including<br>
Ruby 1.8 and JRuby.</p>
<p>However there are requests for testing the availability of the methods without<br>
calling them. It is reasonable if the methods have unavoidable side-effects.<br>
This respond_to? behavior is for such requests.</p>
<p>If we take the reason "we can't really know whether it is supported or<br>
not on some platforms.", we cannot provide a solution for the above<br>
requests.</p>
<p>However I know the reason is actually true even in C.<br>
For example, new Linux system call is provided by glibc but<br>
Ruby runs on older Linux, the system call causes ENOSYS.<br>
We can't really know the system call is supported or not on the running system.</p>
<p>So I recommend "just call and rescue" if possible.</p>
</blockquote>
<p>So then in general, the new functionality is useless and should not be<br>
used, since even for the C implementation you can't know if a method<br>
will fail to invoke successfully. Should an unreliable or useless<br>
feature ever be added?</p>
<ul>
<li>Charlie</li>
</ul>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77602010-01-22T17:28:00Zheadius (Charles Nutter)headius@headius.com
<ul></ul><p>=begin<br>
On Thu, Jan 21, 2010 at 11:27 PM, Yukihiro Matsumoto <a href="mailto:matz@ruby-lang.org" class="email">matz@ruby-lang.org</a> wrote:</p>
<blockquote>
<p>We added a new behavior of defined?/respond_to? to 1.9 for exact same<br>
purpose in more generic way. We are not going to add redundant<br>
feature. If you want to stick with 1.8, JRuby, IronRuby or whatever,<br>
you have to persuade their maintainers.</p>
</blockquote>
<p>Except that as Akira pointed out, even on the C impl you can't know<br>
whether the system itself has stubbed out certain functionality and<br>
won't actually provide it. So everyone that expects respond_to? in<br>
1.9+ to produce a definitive result will still be mistaken. What have<br>
we gained?</p>
<ul>
<li>Charlie</li>
</ul>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77612010-01-22T17:36:52Zheadius (Charles Nutter)headius@headius.com
<ul></ul><p>=begin<br>
On Thu, Jan 21, 2010 at 9:39 PM, Luis Lavena <a href="mailto:luislavena@gmail.com" class="email">luislavena@gmail.com</a> wrote:</p>
<blockquote>
<p>On Thu, Jan 21, 2010 at 9:57 PM, Hongli Lai <a href="mailto:hongli@plan99.net" class="email">hongli@plan99.net</a> wrote:</p>
<blockquote>
<p>[...]</p>
<blockquote>
<ul>
<li>Provide another mechanism for querying specific features, like<br>
Platform.support? :fork</li>
</ul>
</blockquote>
<p>How is this better than calling the method and catching NotImplementedError? Your<br>
check method, although returning a boolean, still calls the method under the hood.<br>
This makes #support? an expensive call which is something I wanted to avoid with<br>
#fork_supported?.</p>
</blockquote>
<p>I might be able to answer that.</p>
<p>While experimenting with Rubinius and MinGW, I've created a C library<br>
that collected at compile time the related information of the<br>
platform, and exposed it as CAPI extension.</p>
<p>That can, using extconf, #define, #ifdef etc the functionality exposed<br>
by the platform you're running on.</p>
<p>In the case of JRuby, that Platform module can evaluate the underlying<br>
OS capabilities and return you true/false without the need of<br>
triggering NotImplementedError</p>
<p>At the end, I believe both fork_supported? and Platform.support? :fork<br>
aim at the same, but the later can serve as API for other<br>
functionality, like symlink, hardlinks, etc.</p>
</blockquote>
<p>Yes, you understand...this is why I proposed it. The general idea is<br>
similar to the RUBY_ENGINE debates: a way to provide a "feature<br>
enumeration" for users.</p>
<p>Using this code:</p>
<p>Platform.supported? :fork</p>
<p>...gives us the opportunity to handle specific keys in specific ways<br>
<em>at runtime</em> rather than having to attach special behavior to all such<br>
methods <em>at compile time</em>. And it does not require that we call fork,<br>
since we can at least know some subset of names people are expecting<br>
to have.</p>
<p>Based on what Tanaka has described about the C implementation, we<br>
could comfortably implement respond_to? to always return true if we<br>
define the method, regardless of whether it would raise an error or<br>
not. Users should expect to rescue errors even if MRI does respond_to?<br>
various methods, since the system itself may have stubbed them out to<br>
produce errors. I'm not sure how the new behavior is actually useful.</p>
<ul>
<li>Charlie</li>
</ul>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77662010-01-22T21:56:06Zvvs (Vladimir Sizikov)vsizikov@gmail.com
<ul></ul><p>=begin<br>
Hi,</p>
<p>On Fri, Jan 22, 2010 at 9:51 AM, Tanaka Akira <a href="mailto:akr@fsij.org" class="email">akr@fsij.org</a> wrote:</p>
<blockquote>
<p>2010/1/22 Charles Oliver Nutter <a href="mailto:headius@headius.com" class="email">headius@headius.com</a>:</p>
<blockquote>
<p>So then in general, the new functionality is useless and should not be<br>
used, since even for the C implementation you can't know if a method<br>
will fail to invoke successfully. Should an unreliable or useless<br>
feature ever be added?</p>
</blockquote>
<p>I (and Vladimir) don't say that it always impossible.</p>
<p>There are cases which is possible.</p>
</blockquote>
<p>Yes, it seems that there are cases when this is possible. But the<br>
problem is that this is not reliable and "portable" (across platforms<br>
and across different implementations) in general case. So this looks<br>
more like a hint rather than a reliable way to check whether some<br>
method is implemented/functional or not. At the end of the day any<br>
robust code still needs to take care of NotImplementedError and<br>
whatnot.</p>
<p>Personally, I think that changing a public API and introducing this<br>
complexity (and special cases like this <em>are</em> an additional<br>
complexity) just to provide some 'hint' is overkill.</p>
<p>I don't think we could do that for JRuby (it will require lots and<br>
lots of changes, ugly special-cases handling for respond_to?, and<br>
still not be 100% reliable), so I just hate to see an incompatibility<br>
where it could have been avoided.</p>
<p>Thanks,<br>
--Vladimir</p>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77722010-01-23T04:25:36Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul></ul><p>=begin<br>
Hi,</p>
<p>In message "Re: <a href="https://blade.ruby-lang.org/ruby-core/27684">[ruby-core:27684]</a> Re: [Feature <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Proposed method: Process.fork_supported? (Rejected)" href="https://redmine.ruby-lang.org/issues/2619">#2619</a>] Proposed method: Process.fork_supported?"<br>
on Fri, 22 Jan 2010 17:27:45 +0900, Charles Oliver Nutter <a href="mailto:headius@headius.com" class="email">headius@headius.com</a> writes:</p>
<p>|Except that as Akira pointed out, even on the C impl you can't know<br>
|whether the system itself has stubbed out certain functionality and<br>
|won't actually provide it. So everyone that expects respond_to? in<br>
|1.9+ to produce a definitive result will still be mistaken. What have<br>
|we gained?</p>
<p>As far as I understand, he only said there are some cases whether the<br>
availability of a feature can only be known at runtime, not impossible<br>
to implement 1.9 behavior. So I want to make your opinion clear. You<br>
don't like the implementation complexity to implement 1.9 respond_to?<br>
behavior, or something else?</p>
<pre><code> matz.
</code></pre>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77752010-01-23T12:06:29Zheadius (Charles Nutter)headius@headius.com
<ul></ul><p>=begin<br>
On Fri, Jan 22, 2010 at 1:25 PM, Yukihiro Matsumoto <a href="mailto:matz@ruby-lang.org" class="email">matz@ruby-lang.org</a> wrote:</p>
<blockquote>
<p>As far as I understand, he only said there are some cases whether the<br>
availability of a feature can only be known at runtime, not impossible<br>
to implement 1.9 behavior. So I want to make your opinion clear. You<br>
don't like the implementation complexity to implement 1.9 respond_to?<br>
behavior, or something else?</p>
</blockquote>
<p>There would definitely be a lot of added complexity to implement this<br>
behavior in JRuby, since we don't know until runtime for <em>most</em><br>
methods whether they'll be supported or not. We build once at release<br>
time, and then the same binary is used on many different platforms.</p>
<p>I would not argue against a feature just because of complexity,<br>
however. In this case, it seems that users will still need to expect<br>
that different platforms might respond_to? a method but still raise<br>
errors at runtime. I don't feel that the added complexity (present but<br>
less in 1.9, more in JRuby/IronRuby) is worth it.</p>
<p>It also seems like JRuby could simply lease 1.8 behavior in place,<br>
since users may have to rescue errors on all implementations anyway.<br>
Have I misunderstood?</p>
<p>Perhaps you could describe what you think the new behavior is supposed<br>
to be? I'm confused now:</p>
<p>Which of these are correct? (referring to the default respond_to?, not<br>
custom ones)</p>
<p>A: respond_to? should return true iff a method is bound on an object's<br>
class or superclasses (i.e. will not raise NoMethodError)<br>
B: respond_to? should return true iff (A) and the method will never<br>
raise NotImplementedError on any platform<br>
C: respond_to? should return true iff (A) and the method will never<br>
raise NotImplementedError on the current platform<br>
D: respond_to? should return true iff (C) and the method will not<br>
raise system-level "not implemented" errors (like ENOTIMPL or ENOSYS)</p>
<p>Case A is 1.8 behavior and easy to support. If it's there, true; if not, false.</p>
<p>Case B is also pretty easy; we'd have to flag methods we know we have<br>
hardcoded to raise NotImplementedError, and respond_to? would check<br>
that flag. It only works for methods that are never implemented on any<br>
platform, however, which makes me wonder why they're there in the<br>
first place.</p>
<p>Case C is hard; we would have to have special-cased code for each such<br>
method to check at runtime if the current platform supports it, and<br>
make a best guess from there. This logic would have to run for every<br>
new process.</p>
<p>Case D is probably not possible without a very large amount of work<br>
and special-casing at compile time or runtime for all platforms.</p>
<p>I'm also curious how this affects Windows behavior, since currently<br>
MRI stubs out many methods to return nil on Windows (like all of 'etc'<br>
library, for example). Should they raise NotImplementedError? Should<br>
they return false for respond_to?.</p>
<ul>
<li>Charlie</li>
</ul>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77932010-01-24T05:56:16Zheadius (Charles Nutter)headius@headius.com
<ul></ul><p>=begin<br>
On Sat, Jan 23, 2010 at 1:50 PM, Caleb Clausen <a href="mailto:vikkous@gmail.com" class="email">vikkous@gmail.com</a> wrote:</p>
<blockquote>
<p>I don't know much about jruby, but I can't see why you say this is so<br>
difficult. It seems to me that fork_supported? (or whatever it should<br>
be called) could be implemented like this:</p>
</blockquote>
<p>Here's fork_supported? on JRuby:</p>
<p>def Process.fork_supported?; false; end</p>
<p>There's no way to fork a JVM properly; too many signal handlers and<br>
threads that just don't propagate properly. In fact, I'd <em>prefer</em><br>
fork_supported? over the respond_to? behavior change.</p>
<blockquote>
<p>Does that not work right in jruby? In the general case, there are many<br>
such system methods that need to be checked; you wouldn't want to<br>
repeat the above for each one. But it can be generalized and dry'd up<br>
a little:</p>
<p>module Platform<br>
SYSCALLNAME2TEST={<br>
:fork => "!!fork{}",<br>
:ppid => "res=Process.ppid; res and res !=0",<br>
#etc<br>
}</p>
<p> eval SYSCALLNAME2TEST.map{|name,test|<br>
"<br>
def #{name}_supported?<br>
return @@#{name}_supported unless @@#{name}_supported==nil<br>
@@#{name}_supported= (#{test})<br>
return @@#{name}_supported<br>
rescue Exception<br>
return @@#{name}_supported=false<br>
end<br>
"<br>
}.join("\n")<br>
end</p>
</blockquote>
<p>Except that calling many methods will have side effects we don't want<br>
to happen, or may have overcomplicated tests, or may not be testable<br>
at all and you don't know until you call them with valid inputs if<br>
they'll work. The general case is basically the halting problem...you<br>
can't determine from inspection whether calling a given<br>
method/function will behave well enough to claim it is "implemented".</p>
<blockquote>
<p>Essentially, you're doing the same kind of tests that configure does,<br>
but at runtime instead of compile time. Maybe you have to do a<br>
different special test for each system call, but that's one line, or<br>
at most a few, for each one. So in all we're talking about, what,<br>
several hundred lines of (ruby) code? I don't see how any of this is<br>
difficult. Tedious, perhaps, but not that difficult. I wouldn't even<br>
characterize it as "a very large amount of work".</p>
</blockquote>
<p>Great, write it for all the system calls that 1.9 reports respond_to?<br>
as false for :) And make sure it works correctly on all the platforms<br>
where people use JRuby. You do have AIX, zLinux, and OpenVMS systems<br>
available, right?</p>
<ul>
<li>Charlie</li>
</ul>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77942010-01-24T06:13:30Zheadius (Charles Nutter)headius@headius.com
<ul></ul><p>=begin<br>
On Fri, Jan 22, 2010 at 9:06 PM, Charles Oliver Nutter<br>
<a href="mailto:headius@headius.com" class="email">headius@headius.com</a> wrote:</p>
<blockquote>
<p>I would not argue against a feature just because of complexity,<br>
however. In this case, it seems that users will still need to expect<br>
that different platforms might respond_to? a method but still raise<br>
errors at runtime. I don't feel that the added complexity (present but<br>
less in 1.9, more in JRuby/IronRuby) is worth it.</p>
</blockquote>
<p>I want to make it clear I'm not just trying to be difficult. Currently<br>
I don't see a simple way for us to observe the new respond_to?<br>
behavior. We know for a fact there are many methods which we bind<br>
regardless of platform because we can't know without calling them if<br>
they're available. If we can't do it simply in JRuby, we won't do<br>
it...and that will mean that the new respond_to? behavior is<br>
ultimately unreliable across implementations. If it's unreliable, it's<br>
no longer useful.</p>
<p>We are certainly open to suggestions on how to implement it. We would<br>
also like to see a specification for how the behavior is supposed to<br>
behave and which methods one might expect to exhibit the behavior.</p>
<p>A quick inspection of 1.9 shows the feature is not even consistent<br>
there. The 'etc' module, for example, still returns nil for any<br>
methods that are not available, and does not appear to respond_to? =><br>
false for any of them.</p>
<p>For the fork case, I think it best for us to not bind the method at<br>
all. There's no good reason for us to bind it, knowing the JVM can't<br>
fork, and so it will respond_to? => false for both 1.8 and 1.9 modes.<br>
If there are other trivial cases, we will probably do the same. But I<br>
don't see how we can guarantee that respond_to? => true will<br>
accurately reflect that a method/function is available on the current<br>
system, and for now we will not support that behavior. If the method<br>
is bound, it will respond_to? => true on JRuby.</p>
<ul>
<li>Charlie</li>
</ul>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=77952010-01-24T06:45:47Zheadius (Charles Nutter)headius@headius.com
<ul></ul><p>=begin<br>
On Sat, Jan 23, 2010 at 3:27 PM, Tanaka Akira <a href="mailto:akr@fsij.org" class="email">akr@fsij.org</a> wrote:</p>
<blockquote>
<p>2010/1/24 Charles Oliver Nutter <a href="mailto:headius@headius.com" class="email">headius@headius.com</a>:</p>
<blockquote>
<p>For the fork case, I think it best for us to not bind the method at<br>
all. There's no good reason for us to bind it, knowing the JVM can't<br>
fork, and so it will respond_to? => false for both 1.8 and 1.9 modes.</p>
</blockquote>
<p>It breaks code which rescue NotImplementedError.</p>
<p>If no fork method, calling fork raise NoMethodError.<br>
rescue NotImplementedError don't rescue NoMethodError.</p>
</blockquote>
<p>Yes, that's certainly true. But etc methods don't raise anything and<br>
don't work either. UNIX socket doesn't even get defined or bound on<br>
Windows, resulting in a NameError when you try to access it. There's<br>
no consistency to any of it.</p>
<p>I did try removing fork, and tests in MRI 1.8 and RubySpec both expect<br>
it to be there, to be private, and to raise NotImplementedError when<br>
called if it's not implemented. So you're right, we can't just remove<br>
it.</p>
<ul>
<li>
<p>Charlie</p>
</li>
<li>
<p>Charlie</p>
</li>
</ul>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=78022010-01-24T19:35:30Zvvs (Vladimir Sizikov)vsizikov@gmail.com
<ul></ul><p>=begin<br>
Hi,</p>
<p>On Sun, Jan 24, 2010 at 5:00 AM, Tanaka Akira <a href="mailto:akr@fsij.org" class="email">akr@fsij.org</a> wrote:</p>
<blockquote>
<p>2010/1/22 Tanaka Akira <a href="mailto:akr@fsij.org" class="email">akr@fsij.org</a>:</p>
<blockquote>
<p>FFI cannot test function availability?</p>
</blockquote>
<p>It seems attach_function in FFI raises FFI::NotFoundError if the specified<br>
function is not found.</p>
<p>I don't understand why the detection is not reliable enough.</p>
</blockquote>
<p>One of the reasons you've mentioned earlier: ENOSYS on POSIX systems<br>
and E_NOTIMPL/ERROR_CALL_NOT_IMPLEMENTED on Windows. So the mere<br>
presence of the method is not a guarantee that it will actually work<br>
on particular system.</p>
<p>Second, MRI behavior treats in such special way only C-level methods,<br>
while all the Ruby-level methods that raise NotImplementedError are<br>
treated differently. So the users of the API need to know this<br>
low-level/implementation detail in order to understand which method<br>
could be checked with respond_to? and which couldn't.</p>
<p>Third, libffi itself is not supported on all platforms/architectures<br>
where JRuby runs. For those cases we can't use it.<br>
And, in some cases/environments the use of native support in JRuby is<br>
prohibited and we can't use it.</p>
<p>Less important, but still worth mentioning:</p>
<p>Also, not all not-implemented features depend on underlying platform,<br>
some are just can't be implemented sanely on JRuby, that's yet another<br>
special case to handle.</p>
<p>JRuby uses jnr-posix 3rd party library (Java Native Runtime - POSIX),<br>
it doesn't provide the capability to check which method is implemented<br>
and which is not. Not to mention that there is a feature to map posix<br>
method names to local platform method names at <em>runtime</em>, which<br>
further complicates the matters, since until you call the method, you<br>
don't know which native method will be actually called. And in some<br>
cases one POSIX-like method is implemented via multiple calls on<br>
particular platfrom (specifically, Windows).</p>
<p>Not to mention that loading FFI (esp. at startup) is costly and we try<br>
to delay it if we can, but with this approach to respond_to? the<br>
method call of respond_to? will cause the loading of FFI. Plus we have<br>
to specialize respond_to? implementations for those classes that could<br>
have "not implemented" methods, this is also not ideal for JVM<br>
performance. And we'd pay some performance penalty for runtime system<br>
capabilities introspection, keeping the lists of "not-implemented"<br>
methods, doing special cases in respond_to?.</p>
<p>So, as you see, this whole thing is just a special case on top of<br>
special case on top of another one. Pretty ugly, and still can't be<br>
100% reliable, and is not really fully documented. While the original<br>
behavior was simple and straightforward: iff there is a method<br>
defined, than respond_to? returns true. This is natural approach in<br>
object-oriented environments, no platform or implementation<br>
capabilities should play a role here.</p>
<p>In those really important cases where is important/critical to<br>
introspect platfrom/API/impl capabilities, there should be a<br>
stand-alone API, and hijacking the base OO instruments for that is not<br>
appropriate, in my opinion.</p>
<p>Thanks,<br>
--Vladimir</p>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=78062010-01-25T02:30:05Zheadius (Charles Nutter)headius@headius.com
<ul></ul><p>=begin<br>
On Sun, Jan 24, 2010 at 10:11 AM, Tanaka Akira <a href="mailto:akr@fsij.org" class="email">akr@fsij.org</a> wrote:</p>
<blockquote>
<p>2010/1/23 Charles Oliver Nutter <a href="mailto:headius@headius.com" class="email">headius@headius.com</a>:</p>
<blockquote>
<p>I'm also curious how this affects Windows behavior, since currently<br>
MRI stubs out many methods to return nil on Windows (like all of 'etc'<br>
library, for example). Should they raise NotImplementedError? Should<br>
they return false for respond_to?.</p>
</blockquote>
<p>It may be good chance to change etc library.</p>
</blockquote>
<p>We originally had etc functions raise NotImplementedError in JRuby,<br>
but quickly discovered that libraries in the wild expect nil results.<br>
Specifically, RubyGems used etc to lookup home dir information, with<br>
nil being a fallback to other methods of doing so.</p>
<p>So there are definitely libraries depending on it, but it would be<br>
nice to make it consistent.</p>
<ul>
<li>Charlie</li>
</ul>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=78692010-01-26T03:34:31Zjonforums (Jon Forums)
<ul></ul><p>=begin</p>
<blockquote>
<p>Thanks but I'm fine. I currently use the following code:</p>
<p>RUBY_ENGINE = defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : "ruby"<br>
def self.fork_supported?</p>
<a name="MRI-gt-192s-respond_to-returns-false-for-methods"></a>
<h1 >MRI >= 1.9.2's respond_to? returns false for methods<a href="#MRI-gt-192s-respond_to-returns-false-for-methods" class="wiki-anchor">¶</a></h1>
<a name="that-are-not-implemented"></a>
<h1 >that are not implemented.<a href="#that-are-not-implemented" class="wiki-anchor">¶</a></h1>
<p>return Process.respond_to?(:fork) &&<br>
RUBY_ENGINE != "jruby" &&<br>
RUBY_ENGINE != "macruby" &&<br>
Config::CONFIG['target_os'] !~ /mswin|windows/<br>
end</p>
</blockquote>
<p>FYIW, 1.9.1p243 of the RC1 from <a href="http://rubyinstaller.org/" class="external">http://rubyinstaller.org/</a> does...</p>
<p>C:\Users\Jon\Documents>ruby -e "require 'rbconfig'; puts Config::CONFIG['target_os']"<br>
mingw32</p>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=78762010-01-26T06:38:18Zluislavena (Luis Lavena)luislavena@gmail.com
<ul></ul><p>=begin<br>
On Mon, Jan 25, 2010 at 2:57 PM, Hongli Lai <a href="mailto:hongli@plan99.net" class="email">hongli@plan99.net</a> wrote:</p>
<blockquote>
<p>On 1/25/10 3:46 PM, Roger Pack wrote:</p>
<blockquote>
<p>I could add the method "OS.fork_supported?" to the OS gem if it would<br>
help the original poster (and/or if it could help make unnecessary the<br>
modification of respond_to? in 1.9.2)</p>
<p>Just thinking out loud.</p>
</blockquote>
<p>Thanks but I'm fine. I currently use the following code:</p>
<p>RUBY_ENGINE = defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : "ruby"<br>
def self.fork_supported?<br>
# MRI >= 1.9.2's respond_to? returns false for methods<br>
# that are not implemented.<br>
return Process.respond_to?(:fork) &&<br>
RUBY_ENGINE != "jruby" &&<br>
RUBY_ENGINE != "macruby" &&<br>
Config::CONFIG['target_os'] !~ /mswin|windows/<br>
end</p>
</blockquote>
<p>JRuby used to respond to target_os as "windows", but none of the<br>
actual Windows implementations respond like that.</p>
<p>VC6 build respond with "mswin32" and GCC build respond with "mingw32"</p>
<p>Please consider these targets can be 64bits too, so /mswin|mingw/ will<br>
be appropriate.</p>
<a name="Cheers"></a>
<h2 >Cheers,<a href="#Cheers" class="wiki-anchor">¶</a></h2>
<h2>Luis Lavena<br>
AREA 17</h2>
<p>Perfection in design is achieved not when there is nothing more to add,<br>
but rather when there is nothing more to take away.<br>
Antoine de Saint-Exupéry</p>
<p>=end</p> Ruby master - Feature #2619: Proposed method: Process.fork_supported?https://redmine.ruby-lang.org/issues/2619?journal_id=78782010-01-26T07:30:19Zhgs (Hugh Sasse)hgs@dmu.ac.uk
<ul></ul><p>=begin<br>
On Tue, 26 Jan 2010, Roger Pack wrote:</p>
<blockquote>
<blockquote>
<p>Thanks but I'm fine. I currently use the following code:</p>
<p>RUBY_ENGINE = defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : "ruby"<br>
def self.fork_supported?<br>
# MRI >= 1.9.2's respond_to? returns false for methods<br>
# that are not implemented.<br>
return Process.respond_to?(:fork) &&<br>
RUBY_ENGINE != "jruby" &&<br>
RUBY_ENGINE != "macruby" &&<br>
Config::CONFIG['target_os'] !~ /mswin|windows/<br>
end</p>
</blockquote>
<p>The kicker is that there may still be edge cases, like ruby on<br>
interix, cygwin, or IronRuby run on mono. Testing it out seems the<br>
only stable way, to me.</p>
<p>MacRuby doesn't support fork?<br>
-r</p>
</blockquote>
<p>For what it is worth, on cygwin I get:</p>
<p>Hugh@Home-PC ~<br>
$ cat fork_supported.rb<br>
require 'rbconfig'</p>
<p>RUBY_ENGINE = defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : "ruby"<br>
def fork_supported?<br>
# MRI >= 1.9.2's respond_to? returns false for methods<br>
# that are not implemented.<br>
return Process.respond_to?(:fork) &&<br>
RUBY_ENGINE != "jruby" &&<br>
RUBY_ENGINE != "macruby" &&<br>
Config::CONFIG['target_os'] !~ /mswin|windows/<br>
end</p>
<p>puts fork_supported?.inspect</p>
<p>Hugh@Home-PC ~<br>
$ ruby !$<br>
ruby fork_supported.rb<br>
true</p>
<p>This is on the older -- Pre Christmas -- cygwin. Last time I updated a machine<br>
to the new major release it wiped /cygwin/home, so I've erred on the side of<br>
caution for now.</p>
<pre><code> Hugh
</code></pre>
<p>=end</p>