unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Is there way to read function invoked and its parameters?
@ 2020-12-27 17:54 Jean Louis
  2020-12-27 18:04 ` Emanuel Berg via Users list for the GNU Emacs text editor
  2020-12-27 19:11 ` Yuri Khan
  0 siblings, 2 replies; 10+ messages in thread
From: Jean Louis @ 2020-12-27 17:54 UTC (permalink / raw)
  To: Help GNU Emacs


Would this concept be possible in Emacs Lisp:

(defun my-function (arg &optional arg-1 arg-2)
  (call-other-function (this-function-called parameters-to-this-function)))

Then the other function would receive something like

 (my-function ARGUMENTS)

Purpose of this is for `tabulated-list-mode' to know how to refresh
it. As the mode could be called by plethora of various ways. It would
be best if I could detect how function was called, with which
parameters and record the fact so that by the key the same function
may be called again.

Problem is not when there is one function or one report, I have
dynamic reports and varieties of reports invoked by variety of
functions and arguments. 

Or maybe there is other way of doing that?

Should I just use local variables to remember the function and its
arguments so that I may invoke it from the report page?






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

* Re: Is there way to read function invoked and its parameters?
  2020-12-27 17:54 Is there way to read function invoked and its parameters? Jean Louis
@ 2020-12-27 18:04 ` Emanuel Berg via Users list for the GNU Emacs text editor
  2020-12-27 19:11 ` Yuri Khan
  1 sibling, 0 replies; 10+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2020-12-27 18:04 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis wrote:

> Would this concept be possible in Emacs Lisp:
>
> (defun my-function (arg &optional arg-1 arg-2)
>   (call-other-function (this-function-called parameters-to-this-function)))
>
> Then the other function would receive something like
>
>  (my-function ARGUMENTS)
>
> Purpose of this is for `tabulated-list-mode' to know how to refresh
> it. As the mode could be called by plethora of various ways. It would
> be best if I could detect how function was called, with which
> parameters and record the fact so that by the key the same function
> may be called again.
>
> Problem is not when there is one function or one report, I have
> dynamic reports and varieties of reports invoked by variety of
> functions and arguments. 
>
> Or maybe there is other way of doing that?

&rest

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal




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

* RE: Is there way to read function invoked and its parameters?
       [not found] <<courier.000000005FE8CA54.00006BFB@stw1.rcdrun.com>
@ 2020-12-27 18:20 ` Drew Adams
  2020-12-27 18:39   ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 10+ messages in thread
From: Drew Adams @ 2020-12-27 18:20 UTC (permalink / raw)
  To: Jean Louis, Help GNU Emacs

> Would this concept be possible in Emacs Lisp:
> 
> (defun my-function (arg &optional arg-1 arg-2)
>   (call-other-function (this-function-called parameters-to-this-function)))
> 
> Then the other function would receive something like
> 
>  (my-function ARGUMENTS)

Reading quickly, so perhaps not understanding the request.
But I'm guessing that advice is what you're looking for.

(elisp) `Advising Functions'

https://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Functions.html



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

* Re: Is there way to read function invoked and its parameters?
  2020-12-27 18:20 ` Drew Adams
@ 2020-12-27 18:39   ` Emanuel Berg via Users list for the GNU Emacs text editor
  2020-12-28  6:57     ` Jean Louis
  0 siblings, 1 reply; 10+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2020-12-27 18:39 UTC (permalink / raw)
  To: help-gnu-emacs

Drew Adams wrote:

>> Would this concept be possible in Emacs Lisp:
>> 
>> (defun my-function (arg &optional arg-1 arg-2)
>>   (call-other-function (this-function-called parameters-to-this-function)))
>> 
>> Then the other function would receive something like
>> 
>>  (my-function ARGUMENTS)
>
> Reading quickly, so perhaps not understanding the request.
> But I'm guessing that advice is what you're looking for.

I'm not understanding either.

What do you mean by "this-function-called"?

You can pass a function as an argument, of course, if that is
the focus point. (it is known by many names, sometimes
"higher-order programming", sometimes "Aggregate functions",
sometimes list or set functions - but to us Lispers it is so
natural it doesn't need a name IMO)

If it is about passing arg-1 and arg-2 you can use arg &rest
args and then concatenate them or by using backquote:

(defun add-all (first &rest rest)
  (apply `(+ ,@(cons first rest))) )

(add-all 1)       ;  1
(add-all 1 3)     ;  4
(add-all 1 3 3 7) ; 14

Or do it some other way with &rest

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal




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

* Re: Is there way to read function invoked and its parameters?
  2020-12-27 17:54 Is there way to read function invoked and its parameters? Jean Louis
  2020-12-27 18:04 ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2020-12-27 19:11 ` Yuri Khan
  2020-12-28  7:07   ` Jean Louis
  1 sibling, 1 reply; 10+ messages in thread
From: Yuri Khan @ 2020-12-27 19:11 UTC (permalink / raw)
  To: Jean Louis; +Cc: Help GNU Emacs

On Mon, 28 Dec 2020 at 00:55, Jean Louis <bugs@gnu.support> wrote:

> Would this concept be possible in Emacs Lisp:
>
> (defun my-function (arg &optional arg-1 arg-2)
>   (call-other-function (this-function-called parameters-to-this-function)))
>
> Then the other function would receive something like
>
>  (my-function ARGUMENTS)
>
> Purpose of this is for `tabulated-list-mode' to know how to refresh
> it. As the mode could be called by plethora of various ways. It would
> be best if I could detect how function was called, with which
> parameters and record the fact so that by the key the same function
> may be called again.

Firstly, ‘tabulated-list-mode’ should probably never be “called” as
such. Instead, modes should be derived from it. (In OOP terms,
‘tabulated-list-mode’ should be treated as an abstract base class.)

‘tabulated-list-mode’ is derived from ‘special-mode’ which binds the
‘g’ key to ‘revert-buffer’. The behavior of ‘revert-buffer’ is
customized by setting ‘revert-buffer-function’ locally.

‘tabulated-list-mode’ sets ‘revert-buffer-function’ to
‘tabulated-list-revert’. The behavior of ‘tabulated-list-revert’ is
customized by adding to ‘tabulated-list-revert-hook’.

> Problem is not when there is one function or one report, I have
> dynamic reports and varieties of reports invoked by variety of
> functions and arguments.
>
> Or maybe there is other way of doing that?
>
> Should I just use local variables to remember the function and its
> arguments so that I may invoke it from the report page?

That is the way, I think.

Be aware that setting a major mode kills all local variables. So you
might want to structure your report mode and functions like this:

    (defvar-local my-report--context …
      "…documentation…")

    (defun my-report--revert ()
      "…documentation…"
      (setq tabulated-list-entries …something computed from
my-report--context…))

    (define-derived-mode my-report-mode tabulated-list-mode "…"
      "…documentation…"
      (add-hook 'tabulated-list-revert #'my-report--revert))

    (defun my-report (…args…)
      "…documentation…"
      (with-current-buffer (…generate a buffer name…)
        (my-report-mode)
        (setq-local my-report--context …some context built from args…)
        (revert-buffer)))



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

* Re: Is there way to read function invoked and its parameters?
  2020-12-27 18:39   ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2020-12-28  6:57     ` Jean Louis
  2020-12-28 16:40       ` Drew Adams
  0 siblings, 1 reply; 10+ messages in thread
From: Jean Louis @ 2020-12-28  6:57 UTC (permalink / raw)
  To: help-gnu-emacs

* Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2020-12-27 21:41]:
> Drew Adams wrote:
> 
> >> Would this concept be possible in Emacs Lisp:
> >> 
> >> (defun my-function (arg &optional arg-1 arg-2)
> >>   (call-other-function (this-function-called parameters-to-this-function)))
> >> 
> >> Then the other function would receive something like
> >> 
> >>  (my-function ARGUMENTS)
> >
> > Reading quickly, so perhaps not understanding the request.
> > But I'm guessing that advice is what you're looking for.
> 
> I'm not understanding either.
> 
> What do you mean by "this-function-called"?
> 
> You can pass a function as an argument, of course, if that is
> the focus point. (it is known by many names, sometimes
> "higher-order programming", sometimes "Aggregate functions",
> sometimes list or set functions - but to us Lispers it is so
> natural it doesn't need a name IMO)
> 
> If it is about passing arg-1 and arg-2 you can use arg &rest
> args and then concatenate them or by using backquote:
> 
> (defun add-all (first &rest rest)
>   (apply `(+ ,@(cons first rest))) )
> 
> (add-all 1)       ;  1
> (add-all 1 3)     ;  4
> (add-all 1 3 3 7) ; 14
> 
> Or do it some other way with &rest

I know I can pass stuff through arguments and I know I could hard code
for each function how it is called. I was rather thinking that maybe
there is functionality where function from inside knows how it was
called and by which arguments. Maybe there is some global variable or
function holding that information. Then I could just pass that
variable to function invoked from that function. Then I would not need
to hard code passing of arguments in hundreds of functions.

Practically I wish to achieve this:

1. Reporting function is invoked, I would like to have program
   remember WHICH reporting function was invoked and by which
   arguments and to pass it to other functions.

2. Other function is called, there are few more hops.

3. The report is shown on screen. Now this reporting function is
   disconnected from the first and I would need a refresh of the
   report after editing or inserting information. The refresh shall
   know exactly how the first reporting function has been invoked.

There are many functions that are at (1) so there is considerable
number of those functions.

For example this is such function that introspect the function being
called:

called-interactively-p is a compiled Lisp function in ‘subr.el’.

(called-interactively-p KIND)

  Probably introduced at or before Emacs version 22.1.

Return t if the containing function was called by ‘call-interactively’.

Maybe there is other mechanism that introspects the function's own name
and function's own arguments.

Then I could do just this:

(defun report (arg1 arg2 arg3)
  (do some stuff)
  (invoke-display (how-this-function-was-called)))

(defun report-1 (arg1 arg2 arg3)
  (do some stuff)
  (invoke-display (how-this-function-was-called)))

(defun report-2 (arg1 arg2 arg3)
  (do some stuff)
  (invoke-display (how-this-function-was-called)))

Instead of doing this:

(defun report (arg1 arg2 arg3)
  (do some stuff)
  (invoke-display '(report arg1 arg2 arg3)))
  
(defun report-1 (arg1 arg2 arg3)
  (do some stuff)
  (invoke-display '(report-1 arg1 arg2 arg3)))

(defun report-2 (arg1 arg2 arg3)
  (do some stuff)
  (invoke-display '(report-2 arg1 arg2 arg3)))

Additionally, it becomes very tedious if I would now need to replace
normal arguments with &rest only for those functions with parameters
to be passed correctly.

I rather prefer having introspection function that looks into itself
and finds out what is its name and what were arguments.




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

* Re: Is there way to read function invoked and its parameters?
  2020-12-27 19:11 ` Yuri Khan
@ 2020-12-28  7:07   ` Jean Louis
  2020-12-28  9:04     ` Yuri Khan
  0 siblings, 1 reply; 10+ messages in thread
From: Jean Louis @ 2020-12-28  7:07 UTC (permalink / raw)
  To: Yuri Khan; +Cc: Help GNU Emacs

* Yuri Khan <yuri.v.khan@gmail.com> [2020-12-27 22:11]:
> Firstly, ‘tabulated-list-mode’ should probably never be “called” as
> such. Instead, modes should be derived from it. (In OOP terms,
> ‘tabulated-list-mode’ should be treated as an abstract base class.)

Alright, I am doing it that way.

> ‘tabulated-list-mode’ is derived from ‘special-mode’ which binds the
> ‘g’ key to ‘revert-buffer’. The behavior of ‘revert-buffer’ is
> customized by setting ‘revert-buffer-function’ locally.
> 
> ‘tabulated-list-mode’ sets ‘revert-buffer-function’ to
> ‘tabulated-list-revert’. The behavior of ‘tabulated-list-revert’ is
> customized by adding to ‘tabulated-list-revert-hook’.

Good information, that is what I have to use.

> Be aware that setting a major mode kills all local variables. So you
> might want to structure your report mode and functions like this:
> 
>     (defvar-local my-report--context …
>       "…documentation…")
> 
>     (defun my-report--revert ()
>       "…documentation…"
>       (setq tabulated-list-entries …something computed from
> my-report--context…))
> 
>     (define-derived-mode my-report-mode tabulated-list-mode "…"
>       "…documentation…"
>       (add-hook 'tabulated-list-revert #'my-report--revert))

The principle for refreshing or reverting is there, that is
right. Only that it is very inconvenient especially if there is large
number of functions.

In the above example I would rather like to pass some dynamically
defined function to add-hook then making many revert functions for
each report.

I am now thinking to employ something like this concept:

(defun my-report (arg1 arg2 arg3)
  (cl-flet my-report--revert ()
	   (my-report arg1 arg2 arg3))
  (invoke-other-function 'my-report--revert))

Then other function can set up hooks by using that function. Does
this sound alright to you?





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

* Re: Is there way to read function invoked and its parameters?
  2020-12-28  7:07   ` Jean Louis
@ 2020-12-28  9:04     ` Yuri Khan
  0 siblings, 0 replies; 10+ messages in thread
From: Yuri Khan @ 2020-12-28  9:04 UTC (permalink / raw)
  To: Yuri Khan, Help GNU Emacs

On Mon, 28 Dec 2020 at 14:08, Jean Louis <bugs@gnu.support> wrote:

> The principle for refreshing or reverting is there, that is
> right. Only that it is very inconvenient especially if there is large
> number of functions.
>
> In the above example I would rather like to pass some dynamically
> defined function to add-hook then making many revert functions for
> each report.
>
> I am now thinking to employ something like this concept:
>
> (defun my-report (arg1 arg2 arg3)
>   (cl-flet my-report--revert ()
>            (my-report arg1 arg2 arg3))
>   (invoke-other-function 'my-report--revert))
>
> Then other function can set up hooks by using that function. Does
> this sound alright to you?

It might be possible but it’s not a good idea. Even if you manage to
keep a function definition in a buffer-local variable, debugging that
is likely going to be unpleasant.



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

* RE: Is there way to read function invoked and its parameters?
  2020-12-28  6:57     ` Jean Louis
@ 2020-12-28 16:40       ` Drew Adams
  2020-12-28 19:58         ` Jean Louis
  0 siblings, 1 reply; 10+ messages in thread
From: Drew Adams @ 2020-12-28 16:40 UTC (permalink / raw)
  To: Jean Louis, help-gnu-emacs

> > > Reading quickly, so perhaps not understanding the request.
> > > But I'm guessing that advice is what you're looking for.

Still not reading this thread carefully, but I
still have the impression that, for what you want
to do, you can use _advice_.

https://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Functions.html

When a function gets called you can do anything,
including introspect the current context,
reporting on it, and reinvoking the called arg
(with the same or different args).  Pretty much
anything.

The only limitation of this approach is that,
like `debug-on-entry', it only takes control
when the function is actually invoked.  Other
than that consideration, you can do pretty
much anything, with the full call context at
hand.



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

* Re: Is there way to read function invoked and its parameters?
  2020-12-28 16:40       ` Drew Adams
@ 2020-12-28 19:58         ` Jean Louis
  0 siblings, 0 replies; 10+ messages in thread
From: Jean Louis @ 2020-12-28 19:58 UTC (permalink / raw)
  To: help-gnu-emacs

* Drew Adams <drew.adams@oracle.com> [2020-12-28 19:41]:
> > > > Reading quickly, so perhaps not understanding the request.
> > > > But I'm guessing that advice is what you're looking for.
> 
> Still not reading this thread carefully, but I
> still have the impression that, for what you want
> to do, you can use _advice_.
> 
> https://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Functions.html
> 
> When a function gets called you can do anything,
> including introspect the current context,
> reporting on it, and reinvoking the called arg
> (with the same or different args).  Pretty much
> anything.

   A more advanced example would be to trace the calls to the process
filter of a process PROC:

     (defun my-tracing-function (proc string)
       (message "Proc %S received %S" proc string))

     (add-function :before (process-filter PROC) #'my-tracing-function)

Maybe you mean similar to that above.

The `process-filer' would be called multiple times by multiple other
functions in the same time and it would mean that I need somehow to
invoke `add-function' dynamically so that each new buffer receives the
"updating function".

This function here is mostly the final function that shall receive
information how to update the entries when entries are edited,
modified, it should invoke new SQL query to fetch fresh entries.
 
(defun rcd-db-report (title entries format table sort-key)
  (let* ((title (generate-new-buffer-name (concat "RCD Database: " title))))
    (let* ((buffer title)
	   (buffer (get-buffer-create buffer))
	   (mode-map (rcd-db-table-mode-map table)))
      ;; (message "Keymap: %s" table)
      (switch-to-buffer-other-window buffer)
      (delete-other-windows)
      (setq tabulated-list-format format)
      (setq tabulated-list-entries entries)
      (setq rcd-db-edited-table table)
      (rcd-db-list-mode) ;; TODO if I move it from this line, weird things happen
      (use-local-map mode-map) ;; TODO if I move it from this line, weird things happen
      (tabulated-list-init-header)
      (setq tabulated-list-padding 1))
      (setq tabulated-list-sort-key sort-key)
      ;;(tabulated-list-init-header)
      (tabulated-list-print t)))

Then there is plethora of other functions that are hoping over
`rcd-db-sql-report-two' (but i could remove hops) and invoking the
above function.

(defun cf-tabulated-accounts-list ()
  (interactive)
  (let* ((sql "SELECT accounts_id, accounts_name FROM accounts"))
    (rcd-db-sql-report-two "Accounts" sql [("ID" 5 t) ("Account" 80 t)] "accounts" nil)))

(defun cf-tabulated-accounts-without-country ()
  (interactive)
  (let* ((sql "SELECT accounts_id, accounts_name FROM accounts WHERE accounts_billingcountry IS NULL"))
    (rcd-db-sql-report-two "Accounts" sql [("ID" 5 t) ("Account" 80 t)] "accounts" nil)))

(defun cf-tabulated-account (id)
  (let* ((sql (format "SELECT accounts_id, accounts_name FROM accounts WHERE accounts_id = %s" id)))
    (rcd-db-sql-report-two "Accounts" sql [("ID" 5 t) ("Account" 80 t)] "accounts" nil)))

Let us say there is invoked function `(cf-tabulated-account 2)' then
one solution that I can think of is to pass it as in the arguments,
maybe making a macro out of it.

(defun cf-tabulated-account (id)
  (let* ((sql (format "SELECT accounts_id, accounts_name FROM accounts WHERE accounts_id = %s" id)))
    (rcd-db-sql-report-two "Accounts" sql [("ID" 5 t) ("Account" 80 t)] "accounts" nil `'(cf-tabulated-account ,id))))

Then it would arrive to first function to be invoked to refresh the entries.

Just thinking how to do it right. It requires a lot of changes to many various functions.





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

end of thread, other threads:[~2020-12-28 19:58 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-12-27 17:54 Is there way to read function invoked and its parameters? Jean Louis
2020-12-27 18:04 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-27 19:11 ` Yuri Khan
2020-12-28  7:07   ` Jean Louis
2020-12-28  9:04     ` Yuri Khan
     [not found] <<courier.000000005FE8CA54.00006BFB@stw1.rcdrun.com>
2020-12-27 18:20 ` Drew Adams
2020-12-27 18:39   ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-28  6:57     ` Jean Louis
2020-12-28 16:40       ` Drew Adams
2020-12-28 19:58         ` Jean Louis

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).