Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature to pass additional arguments on to coderef #3

Open
dboehmer opened this issue Mar 28, 2020 · 5 comments
Open

Add feature to pass additional arguments on to coderef #3

dboehmer opened this issue Mar 28, 2020 · 5 comments
Assignees
Milestone

Comments

@dboehmer
Copy link

Thank you for this great module. I've written minimal versions of this multiple times and have just found this concise solution on CPAN! 👍

Would you mind adding a feature that you can provide additional arguments that get passed on to the provided coderef?

my $guard = guard { do_something_with_foo(@_) }, $foo, $bar, ...;

The difference to

my $guard = guard { do_something_with_foo($foo, $bar, ...) };

is obviously the execution time of $foo etc. I have a long living LWP::UserAgent object and need to temporarily set its max_redirect to 0. I'd love to write this:

my $ua = LWP::Simple->new();
...
subtest "test some redirect" => sub {
    my $guard = guard { $ua->max_redirect(@_) }, $ua->max_redirect; # will restore original value 
    $ua->max_redirect(0); # temporarily
    ...
};
...

As far as I studied your code no existing code could be using any additional arguments and they could easily stored in @$self.

I'd send a PR if you consider adding this feature.

@karenetheridge
Copy link
Contributor

Not the author, but I think you can achieve that with the use of the curry module (https://metacpan.org/pod/curry).

@dboehmer
Copy link
Author

I've never used curry before but just had I a look at it. I don't get how this would help here, though.

The documentation of curry is all about weak references. Instead my problem is

  1. I want to run code automatically once the current scope block ends: Scope::Guard solves this by establishing a variable that calls my code once its garbage-collected.
  2. For that I need to save some information (the original value of max_redirect) for the meantime.

This issue is only about how to conveniently save that information in (2). Without that I need to write

my $original_max_redirect = $ua->max_redirect;
my $guard = guard { $ua->max_redirect($original_max_redirect) } # will restore original value 
$ua->max_redirect(0); # temporarily
...

This could be shortened by passing the original value along. How could curry help here? If I am just not getting it, please be as kind as posting an example code.

@karenetheridge
Copy link
Contributor

The documentation of curry is all about weak references.

Not at all; it's about wrapping up extra arguments in a closure for re-use. You can write the closure yourself, but curry does it with shorter code.

This is fairly simple; does this do what you're looking for?

{ # begin new scope
    my $original_max_redirect = $ua->max_redirect;
    my $guard = guard { $ua->max_redirect($original_max_redirect) };
    $ua->max_redirect(0);
    ... test code here...
}

@dboehmer
Copy link
Author

Yeah, this is the obvious plain version. I thought I could save that extra line and it might be a neat feature of Scope::Guard anyway as @_ is completely unused at the moment.

Sorry, but how would the shorter code look like using curry?

@karenetheridge
Copy link
Contributor

instead of

    my $original_max_redirect = $ua->max_redirect;
    my $guard = guard { $ua->max_redirect($original_max_redirect) };

you could do:

    use curry;
    my $guard = guard $ua->curry::max_redirect($ua->max_redirect);

@chocolateboy chocolateboy self-assigned this Jul 9, 2020
@chocolateboy chocolateboy added this to the v1.0.0 milestone Jan 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants