ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:89680] [Ruby trunk Feature#15277] at_exec
       [not found] <redmine.issue-15277.20181102192347@ruby-lang.org>
@ 2018-11-02 19:23 ` ruby-core
  2018-11-02 21:14   ` [ruby-core:89685] " Eric Wong
  2018-11-03  0:05 ` [ruby-core:89686] " ruby-core
  2018-11-04 15:25 ` [ruby-core:89707] " shevegen
  2 siblings, 1 reply; 5+ messages in thread
From: ruby-core @ 2018-11-02 19:23 UTC (permalink / raw
  To: ruby-core

Issue #15277 has been reported by marcandre (Marc-Andre Lafortune).

----------------------------------------
Feature #15277: at_exec
https://bugs.ruby-lang.org/issues/15277

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version: 
----------------------------------------
There's currently no easy way to have code executed before a subsequent call to `exec`. One has to monkey-patch the builtin method.

I'd like to propose a new method `at_exec` that would be very similar to `at_exit`, except that the callbacks are triggered before the current process is replaced by the external command.

```
# This would output "Hello", "Bye", and "Foo"
at_exec { puts "Bye!" }
puts "Hello"
exec "echo Foo"
```

Use case: we roll our own in `DeepCover`. Some test suites will call `exec`, and we need to store our counters before that happens.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:89685] Re: [Ruby trunk Feature#15277] at_exec
  2018-11-02 19:23 ` [ruby-core:89680] [Ruby trunk Feature#15277] at_exec ruby-core
@ 2018-11-02 21:14   ` Eric Wong
  0 siblings, 0 replies; 5+ messages in thread
From: Eric Wong @ 2018-11-02 21:14 UTC (permalink / raw
  To: ruby-core

ruby-core@marc-andre.ca wrote:
> https://bugs.ruby-lang.org/issues/15277

Would this work for subprocesses? (system, spawn, ``, popen, ...)
(if so, it would defeat vfork optimization we do under Linux)

> There's currently no easy way to have code executed before a subsequent call
> to `exec`. One has to monkey-patch the builtin method.
> 
> Use case: we roll our own in `DeepCover`. Some test suites will call `exec`,
> and we need to store our counters before that happens.

As described above, Ruby already has a mechanism for hooking
existing method calls.  I tend to avoid monkey patching because
it leads to surprising behavior.  However, `at_exec` would have
the SAME surprises as monkey-patching.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:89686] [Ruby trunk Feature#15277] at_exec
       [not found] <redmine.issue-15277.20181102192347@ruby-lang.org>
  2018-11-02 19:23 ` [ruby-core:89680] [Ruby trunk Feature#15277] at_exec ruby-core
@ 2018-11-03  0:05 ` ruby-core
  2018-11-03 22:49   ` [ruby-core:89702] " Eric Wong
  2018-11-04 15:25 ` [ruby-core:89707] " shevegen
  2 siblings, 1 reply; 5+ messages in thread
From: ruby-core @ 2018-11-03  0:05 UTC (permalink / raw
  To: ruby-core

Issue #15277 has been updated by marcandre (Marc-Andre Lafortune).


normalperson (Eric Wong) wrote:
>  Would this work for subprocesses? (system, spawn, ``, popen, ...)

I'm not sure I understand the question. `exec` effectively terminates the Ruby process although the `at_exit` callbacks are not called. `system`, `spawn`, etc... don't do such a thing and would thus would not call the `at_exec` callbacks.

> Ruby already has a mechanism for hooking existing method calls

Right. I believe that monkey-patching builtin method calls is something that should be highly discouraged though.

>  However, `at_exec` would have the SAME surprises as monkey-patching.

Maybe so. If (god forbid!) there are multiple such monkey-patches, each with their own callback queues and potentially slightly different implementations, than there would be more surprises.

I imagine that the need of calling `at_exec` is rare though, and my goal is not really to minimize surprises. My goal is to make it easier & nicer to get that result, and avoid having monkey patching as the "official solution" to this issue. We can't even prepend a module to intercept the call to `exec`, so we have to do the alias_method chaining.

----------------------------------------
Feature #15277: at_exec
https://bugs.ruby-lang.org/issues/15277#change-74727

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version: 
----------------------------------------
There's currently no easy way to have code executed before a subsequent call to `exec`. One has to monkey-patch the builtin method.

I'd like to propose a new method `at_exec` that would be very similar to `at_exit`, except that the callbacks are triggered before the current process is replaced by the external command.

```
# This would output "Hello", "Bye", and "Foo"
at_exec { puts "Bye!" }
puts "Hello"
exec "echo Foo"
```

Use case: we roll our own in `DeepCover`. Some test suites will call `exec`, and we need to store our counters before that happens.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:89702] Re: [Ruby trunk Feature#15277] at_exec
  2018-11-03  0:05 ` [ruby-core:89686] " ruby-core
@ 2018-11-03 22:49   ` Eric Wong
  0 siblings, 0 replies; 5+ messages in thread
From: Eric Wong @ 2018-11-03 22:49 UTC (permalink / raw
  To: ruby-core

ruby-core@marc-andre.ca wrote:
> normalperson (Eric Wong) wrote:
> >  Would this work for subprocesses? (system, spawn, ``,
> >  popen, ...)
> 
> I'm not sure I understand the question. `exec` effectively
> terminates the Ruby process although the `at_exit` callbacks
> are not called. `system`, `spawn`, etc... don't do such a
> thing and would thus would not call the `at_exec` callbacks.

system, spawn, etc. implicitly call exec, but only after fork/vfork
in a child.

Anyways, I'm still against this proposal because there is an
existing and generic way to support such behavior.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:89707] [Ruby trunk Feature#15277] at_exec
       [not found] <redmine.issue-15277.20181102192347@ruby-lang.org>
  2018-11-02 19:23 ` [ruby-core:89680] [Ruby trunk Feature#15277] at_exec ruby-core
  2018-11-03  0:05 ` [ruby-core:89686] " ruby-core
@ 2018-11-04 15:25 ` shevegen
  2 siblings, 0 replies; 5+ messages in thread
From: shevegen @ 2018-11-04 15:25 UTC (permalink / raw
  To: ruby-core

Issue #15277 has been updated by shevegen (Robert A. Heiler).


> I imagine that the need of calling at_exec is rare though

I think something similar could be said about at_exit. While I
think it is fine that it exists, I found that in larger projects
it can be quite annoying if some other project uses at_exit.

For example, this old project makes use of at_exit:

    https://rubygems.org/gems/cgi-exception

It prints exceptions that a .cgi script has onto the web-page,
a bit similar as to how .php files work.

I copy/paste the code so that it is easier to read:

    ## when process exit, print exception if exception raised
      at_exit do
        if $!
          ex = $!
          CGIExceptionPrinter.new($_header_printed).handle(ex)
          if defined?(EditorKicker)
            EditorKicker.handle(ex) #if ENV['EDITOR_KICKER']
          end
        end
      end

The display of where an error line occurs is nice, but I found
that at_exit events can be difficult to control and lead to
some more complexity. It may not always be easy to find out
which at_exit is triggered first and where. This is largely
a reason why I avoid at_exit, even if it may be useful.

While I am neutral on the proposal here, thus not having a pro
or con opinion, I think we can generalize this a bit by looking
not only at at_exit, but also autoload. Autoload is similar in
some ways in that it "says": "if a constant is first used and
unknown, load these files". So it also is a bit like an at-"event"
or a hook. There are other hooks/events in ruby; catch-sigint
or the included, inherited etc...

Perhaps it may be useful to easily specific "at" events.

So for example, rather than a pre-defined at_exec method,
there could be a simpler "build" API that allows such events
to happen. Like the various attr APIs like attr_reader,
attr_writer and so on.

Perhaps like this way:

    define_at :exec { puts "Bye!" }
    at_exec { puts "Bye!" }

(I guess the first line needs (), but I only wanted to demonstrate
the idea here. This would generate at_* methods, without having
them pre-defined.)

Of course I don't know if Marc-Andre agrees to any of this - I only
wanted to give this as a rough idea what I mean. :)

You could then think of at_exit as being similarly defined. And any
other methods that a ruby hacker may want to use, via an "at_" prefix.

But anyway, I do not want to distract from the suggestion. Marc-Andre
also gave a use case and I think even if one may not like the special
case of at_exec, I think the usefulness of the described use case is
still a possibility.

Ultimately the hook/events/conditional_code execution outside of 
more "classical" if/else checks is something that matz may have to
think about. (On an unimportant side note, the old programming
language LPC, used for some old text-MUDs, also had certain events
and hooks that could be "attached" onto mobs/monsters/npcs, to 
enable certain additional ad-hoc functionality or behaviour, without
this having to necessarily be written into the files that would be
used to create the initial object at hand. Of course ruby is a lot
more flexible than LPC, but I wanted to mention this since such 
conditional hooks also existed in older languages, at the least
to some extent.)

----------------------------------------
Feature #15277: at_exec
https://bugs.ruby-lang.org/issues/15277#change-74750

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version: 
----------------------------------------
There's currently no easy way to have code executed before a subsequent call to `exec`. One has to monkey-patch the builtin method.

I'd like to propose a new method `at_exec` that would be very similar to `at_exit`, except that the callbacks are triggered before the current process is replaced by the external command.

```
# This would output "Hello", "Bye", and "Foo"
at_exec { puts "Bye!" }
puts "Hello"
exec "echo Foo"
```

Use case: we roll our own in `DeepCover`. Some test suites will call `exec`, and we need to store our counters before that happens.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-11-04 15:25 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <redmine.issue-15277.20181102192347@ruby-lang.org>
2018-11-02 19:23 ` [ruby-core:89680] [Ruby trunk Feature#15277] at_exec ruby-core
2018-11-02 21:14   ` [ruby-core:89685] " Eric Wong
2018-11-03  0:05 ` [ruby-core:89686] " ruby-core
2018-11-03 22:49   ` [ruby-core:89702] " Eric Wong
2018-11-04 15:25 ` [ruby-core:89707] " shevegen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).