* Iterating over buffer lines
@ 2023-06-16 22:19 Joshua Lambert
2023-06-17 0:10 ` Platon Pronko
0 siblings, 1 reply; 6+ messages in thread
From: Joshua Lambert @ 2023-06-16 22:19 UTC (permalink / raw)
To: help-gnu-emacs
I have created some functions that make changes to one buffer line of
a csv file. Let's call those functions a, b and c. Each of those take
one or more arguments. I want to create a separate interactive
function that does what function a, b, and c do, but on every line of
the region. I successfully created a function (act-on-region-by-line)
to go through all lines in a region and then call function a, function
b, or function c. But, It seems redundant to have multiple functions
that have 9-15 lines similar and one line different, the one that
specifies function a, b or c. What is the best way to be efficient in
this situation?
I have attempted to pass function b as a parameter, but I am slow to
understand how to do that. Is that the best way, or is there another?
Thanks,
J Lambert
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Iterating over buffer lines
2023-06-16 22:19 Iterating over buffer lines Joshua Lambert
@ 2023-06-17 0:10 ` Platon Pronko
2023-06-17 3:28 ` Joshua Lambert
0 siblings, 1 reply; 6+ messages in thread
From: Platon Pronko @ 2023-06-17 0:10 UTC (permalink / raw)
To: Joshua Lambert, help-gnu-emacs
On 2023-06-17 06:19, Joshua Lambert wrote:
> I have created some functions that make changes to one buffer line of
> a csv file. Let's call those functions a, b and c. Each of those take
> one or more arguments. I want to create a separate interactive
> function that does what function a, b, and c do, but on every line of
> the region. I successfully created a function (act-on-region-by-line)
> to go through all lines in a region and then call function a, function
> b, or function c. But, It seems redundant to have multiple functions
> that have 9-15 lines similar and one line different, the one that
> specifies function a, b or c. What is the best way to be efficient in
> this situation?
>
> I have attempted to pass function b as a parameter, but I am slow to
> understand how to do that. Is that the best way, or is there another?
>
> Thanks,
> J Lambert
>
It's a bit difficult to understand what the problem is without seeing the code. Can you show the code for your latest attempt?
Yes, passing function as a parameter seems to be the best way. And partial function application might be useful here as well.
--
Best regards,
Platon Pronko
PGP 2A62D77A7A2CB94E
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Iterating over buffer lines
2023-06-17 0:10 ` Platon Pronko
@ 2023-06-17 3:28 ` Joshua Lambert
2023-06-17 4:48 ` tomas
2023-06-18 1:17 ` Platon Pronko
0 siblings, 2 replies; 6+ messages in thread
From: Joshua Lambert @ 2023-06-17 3:28 UTC (permalink / raw)
To: Platon Pronko; +Cc: help-gnu-emacs
OK. See below. I'm trying to avoid reusing most of the code in
function my-act-on-region-by-line. There are multiple functions that
correct data errors in a csv file and I want to be able to
interactively run one of those corrections at a time. The resulting
string will be inserted at the beginning of each line. That all works,
I'm just trying not to have so much code repetition.
(defun my-act-on-region-by-line (some-function &optional beg end)
"Perform a function on the current line or each line of the region.
Each SOME-FUNCTION must return a string."
(let ((beg2 (if (region-active-p)
beg
(line-beginning-position)))
(end2 (if (region-active-p)
end
(line-end-position))))
(save-excursion
(save-restriction
(narrow-to-region beg2 end2)
(goto-char (point-min))
(while (not (eobp))
(goto-char (line-beginning-position))
(insert some-chosen-function) ;; Inserts text after a
function transforms it.
(insert my-separator)
(forward-line)))))
(defun my-paste-corrected-spacing (&optional field-num beg end)
"Correct spacing in a string and paste it at the beginning of a line.
Interactively, BEG and END are the region."
(interactive "*p\nr")
(my-act-on-region-by-line (some-function-to-correct-spacing field-num)
beg
end))
(defun some-function-to-correct-spacing (field-num)
"Function that creates a correctly spaced string."
........
On Fri, Jun 16, 2023 at 7:10 PM Platon Pronko <platon7pronko@gmail.com> wrote:
>
> On 2023-06-17 06:19, Joshua Lambert wrote:
> > I have created some functions that make changes to one buffer line of
> > a csv file. Let's call those functions a, b and c. Each of those take
> > one or more arguments. I want to create a separate interactive
> > function that does what function a, b, and c do, but on every line of
> > the region. I successfully created a function (act-on-region-by-line)
> > to go through all lines in a region and then call function a, function
> > b, or function c. But, It seems redundant to have multiple functions
> > that have 9-15 lines similar and one line different, the one that
> > specifies function a, b or c. What is the best way to be efficient in
> > this situation?
> >
> > I have attempted to pass function b as a parameter, but I am slow to
> > understand how to do that. Is that the best way, or is there another?
> >
> > Thanks,
> > J Lambert
> >
>
> It's a bit difficult to understand what the problem is without seeing the code. Can you show the code for your latest attempt?
>
> Yes, passing function as a parameter seems to be the best way. And partial function application might be useful here as well.
>
> --
> Best regards,
> Platon Pronko
> PGP 2A62D77A7A2CB94E
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Iterating over buffer lines
2023-06-17 3:28 ` Joshua Lambert
@ 2023-06-17 4:48 ` tomas
[not found] ` <CAGGu9j1gub_8kb92kkD30QmxLmZz8XJrwhyAPtYONE3OLe_zew@mail.gmail.com>
2023-06-18 1:17 ` Platon Pronko
1 sibling, 1 reply; 6+ messages in thread
From: tomas @ 2023-06-17 4:48 UTC (permalink / raw)
To: Joshua Lambert; +Cc: Platon Pronko, help-gnu-emacs
[-- Attachment #1: Type: text/plain, Size: 2422 bytes --]
On Fri, Jun 16, 2023 at 10:28:45PM -0500, Joshua Lambert wrote:
> OK. See below. I'm trying to avoid reusing most of the code in
> function my-act-on-region-by-line. There are multiple functions that
> correct data errors in a csv file and I want to be able to
> interactively run one of those corrections at a time. The resulting
> string will be inserted at the beginning of each line. That all works,
> I'm just trying not to have so much code repetition.
>
> (defun my-act-on-region-by-line (some-function &optional beg end)
> "Perform a function on the current line or each line of the region.
> Each SOME-FUNCTION must return a string."
> (let ((beg2 (if (region-active-p)
> beg
> (line-beginning-position)))
> (end2 (if (region-active-p)
> end
> (line-end-position))))
> (save-excursion
> (save-restriction
> (narrow-to-region beg2 end2)
> (goto-char (point-min))
> (while (not (eobp))
> (goto-char (line-beginning-position))
> (insert some-chosen-function) ;; Inserts text after a
> function transforms it.
> (insert my-separator)
The above means that you are inserting stuff at the beginning of the
current line, right?
> (forward-line)))))
... and this assumes that your `some-chosen-function' doesn't mess
"too much" with point.
>
> (defun my-paste-corrected-spacing (&optional field-num beg end)
> "Correct spacing in a string and paste it at the beginning of a line.
> Interactively, BEG and END are the region."
> (interactive "*p\nr")
> (my-act-on-region-by-line (some-function-to-correct-spacing field-num)
> beg
> end))
>
> (defun some-function-to-correct-spacing (field-num)
> "Function that creates a correctly spaced string."
> ........
I can't /see/ it, but I have a hunch that this function expects
to /replace/ the line by something else. The was it is called
above, its result is /inserted/ in front of the line in question,
right?
Perhaps it's clear to you, but if yes, it doesn't come across:
what is the exact interface between your outer function and
the one called by it?
I.e.: do you need to (save-excursion ...) around `some-chosen-function'?
What do you do with its result? That kind of things.
Cheers
--
t
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Iterating over buffer lines
2023-06-17 3:28 ` Joshua Lambert
2023-06-17 4:48 ` tomas
@ 2023-06-18 1:17 ` Platon Pronko
1 sibling, 0 replies; 6+ messages in thread
From: Platon Pronko @ 2023-06-18 1:17 UTC (permalink / raw)
To: Joshua Lambert; +Cc: help-gnu-emacs
On 2023-06-17 11:28, Joshua Lambert wrote:
> OK. See below. I'm trying to avoid reusing most of the code in
> function my-act-on-region-by-line. There are multiple functions that
> correct data errors in a csv file and I want to be able to
> interactively run one of those corrections at a time. The resulting
> string will be inserted at the beginning of each line. That all works,
> I'm just trying not to have so much code repetition.
>
> (defun my-act-on-region-by-line (some-function &optional beg end)
> "Perform a function on the current line or each line of the region.
> Each SOME-FUNCTION must return a string."
> (let ((beg2 (if (region-active-p)
> beg
> (line-beginning-position)))
> (end2 (if (region-active-p)
> end
> (line-end-position))))
> (save-excursion
> (save-restriction
> (narrow-to-region beg2 end2)
> (goto-char (point-min))
> (while (not (eobp))
> (goto-char (line-beginning-position))
> (insert some-chosen-function) ;; Inserts text after a
> function transforms it.
> (insert my-separator)
> (forward-line)))))
>
> (defun my-paste-corrected-spacing (&optional field-num beg end)
> "Correct spacing in a string and paste it at the beginning of a line.
> Interactively, BEG and END are the region."
> (interactive "*p\nr")
> (my-act-on-region-by-line (some-function-to-correct-spacing field-num)
> beg
> end))
>
> (defun some-function-to-correct-spacing (field-num)
> "Function that creates a correctly spaced string."
> ........
>
The code you pasted doesn't seem to work, for example because some-chosen-function doesn't exist. So I have trouble understanding what your problem is - is the pasted code fragment the example of duplication, or your approach to reducing duplication in code that I don't see?
If it's example of duplication (between my-paste-corrected-spacing and some other similar functions), then it looks like the duplication is minimal - function name, docstring, and underlying function are different. So actual duplication is 2-3 lines - `(&optional field-num beg end)`, `(interactive "*p\nr")`, and `my-act-on-region-by-line` parts. You can create a macro to reduce that duplication even further, but it seems that we are hitting diminishing returns here.
If the code as shown is already an attempt to reduce duplication then it looks like you are almost there - you just need to use `(apply some-function)` to call the function that you pass to my-act-on-region-by-line.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-06-18 1:17 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-16 22:19 Iterating over buffer lines Joshua Lambert
2023-06-17 0:10 ` Platon Pronko
2023-06-17 3:28 ` Joshua Lambert
2023-06-17 4:48 ` tomas
[not found] ` <CAGGu9j1gub_8kb92kkD30QmxLmZz8XJrwhyAPtYONE3OLe_zew@mail.gmail.com>
2023-06-17 19:17 ` tomas
2023-06-18 1:17 ` Platon Pronko
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).