Re^3: Can someone please write a *working* JSON module
by haj (Vicar) on Oct 26, 2021 at 10:42 UTC
|
I won't argue in favor or against exceptions, but your points contain some inaccuracies.
- die and croak can deliver objects to $@ quite fine. If you croak with an object, that object is passed to die and you can evaluate that object in $@ as you like. It loses the stacktrace, but then, you don't get a stacktrace by returning error integers/objects as well.
- The debugger has no problems with eval. You wouldn't know, of course, if you never used it, but then why raise the issue?
- Also, to clarify something you wrote in Re^4: Can someone please write a *working* JSON module: eval BLOCK does not "spawn a new interpreter".
If you don't like the keyword eval, then you can have try/catch as of Perl 5.34. There are also several CPAN modules offering that, and of course they're all eval wrappers, because that's just the mechanism Perl always had. The point of the modules isn't about using different words, but avoiding the pitfalls with localized $@ (The docs of Try::Tiny give some details).
| [reply] [d/l] [select] |
|
|
If you croak with an object, that object is passed to die and you can evaluate that object in $@ as you like. It loses the stacktrace, I think I just said that.
The debugger has no problems with eval. i did not say it has, I talked about a hypothetical eyesore, i.e. if it's not seamless, for example line numbers etc. in order to get some input from others who use it to agree or disagree. It would be useful to know your experience on the subject. The process of filing an application to express opinions about something that I don't use but it has an effect on the "croak debate" was taking too long so I thought I say that on the understanding that when the debate police intervenes I will show them the receipt which they can radio it to debate-HQ and get the OK. Sorry but nitpicking is not something I react nicely to.
eval BLOCK does not "spawn a new interpreter" you are clarifying what exactly? "answering" is the appropriate word as I was asking (I think it spawns a new interpreter right?) after googling it without finding what the exact mechanism is. From experimenting with perlembed I got the impression, that eval_[sp]v are creating a new interpreter. I would really be interested to know the exact mechanism if you want to elaborate your answer?
Edit: after cooling down, apologies for my tone, to all.
thanks
| [reply] [d/l] [select] |
Re^3: Can someone please write a *working* JSON module
by Anonymous Monk on Oct 26, 2021 at 08:48 UTC
|
It doesn't have to be a dichotomy. Exceptions can be used when you need to fail the operation and jump in an overall exception handler multiple functions above in the call stack. Success/error return values (preferably when they are of different types and the compiler can make sure you're not using the success type in the error branch, a.k.a. the Optional<Success, Failure> idiom) can be used when you can check for and handle the error right away.
People who use exceptions won't argue in favour of code like the following:
eval { step_1(); 1; } or handle_error_1();
eval { step_2(); 1; } or handle_error_2();
eval { step_3(); 1; } or handle_error_3();
eval { step_4(); 1; } or handle_error_4();
That's just more typing for the same result as
step_1() or handle_error_1();
step_2() or handle_error_2();
step_3() or handle_error_3();
step_4() or handle_error_4();
On the other hand, if an error means the whole operation should be aborted and the individual steps signal that by raising an exception, we can write it as
try {
step_1();
step_2();
step_3();
step_4();
} catch {
handle_overall_error();
};
and still be sure that when the error happens, (1) any resources will be cleaned up safely by desctructors and (2) the following steps won't be taken.
By the way, why do you dislike eval? I mean, I don't like eval EXPR either, but what's wrong with eval BLOCK? | [reply] [d/l] [select] |
|
|
I agree, your 1st snippet is bad form. And also the 3rd snippet looks better than the 2nd but the handle_overall_error() must include (for me) the logic of 2nd snippet in order to deduce what really happened, in which step the error really is. In theory it looks nice and compact. In practice, grouping step_1, 2 3 and 4 like this just happens in toy-cases and if they are grouped naturally like this then why not grouping them in a sub. Anyway. I get the point and thanks for the demonstration.
By the way, why do you dislike eval? I mean, I don't like eval EXPR either, but what's wrong with eval BLOCK?
yes I was talking about eval BLOCK as well. Micro-optimisation mostly (mea culpa), I think it spawns a new interpreter right? I am this kind of person that I hate taking the car to the corner shop because I visualise horror: the engine metals screaching, burning, rubbing together, aching and suffering just because I am in need of a cigarette. So I invariably walked until I gave it up altogether.
| [reply] [d/l] [select] |
|
|
I think it spawns a new interpreter right
It definitely doesn't. eval BLOCK just pushes a 'EVAL' context onto the context stack, in a similar way that a sub call pushes a 'SUB' context, and a bare block pushes a 'LOOP_PLAIN' context. A context is just a type flag and a bit of saved state. On normal scope exit, the context is popped and the saved state restored (e.g. @_ restored on return from a sub). On an exception (die, croak etc), the perl interpreter keeps popping contexts (and restoring the saved state in each) until it hits an EVAL context or empties the context stack.
The context stack is what caller() examines (in part).
eval $string has a slow preceding step where it has to call the parser and compile the string into something resembling a sub, then it calls that 'sub' by pushing an EVAL context as with the block case.
Benchmarks show that eval BLOCK has roughly the same overhead as calling a sub with no arguments.
Dave.
| [reply] |
|
|
|
|
I think it spawns a new interpreter right?
Well, eval_sv and eval_pv are related to eval EXPR, not eval BLOCK. There's obviously some performance lost, but not as much as PerlInterpreter * my_perl = perl_alloc(); perl_construct(my_perl); perl_parse(my_perl, NULL, argc, argv, (char **)NULL); perl_run(my_perl); perl_destruct(my_perl); perl_free(my_perl);. New interpreters are constructed for every thread, with tied variables handling access to shared variables, but I don't think a separate interpreter is needed for every eval. eval EXPR additionally spends time in the parser, but eval BLOCK uses the already-parsed data structures.
I've spent a few minutes skimming the source. Perhaps the die() destination and the use feature 'try' entry point could be a good place to start, but I'm not enough of an expert to judge what's really happening here. Though I'm sure it's the same interpreter.
| [reply] [d/l] [select] |
|
|
Re^3: Can someone please write a *working* JSON module
by Aldebaran (Curate) on Oct 28, 2021 at 07:02 UTC
|
I get all my json tools from the software that I've replicated of bliako's. Part of "tribal knowledge" is to know that M. Lehmann has left the fold. I wish there were a way to have perl know which modules are un-maintained, but one man's bug is another's feature.
I can't say: I have never used the debugger
How is it possible that you have never used the debugger?
| [reply] |
|
|
| [reply] [d/l] |
|
|
| [reply] |
|
|
> How is it possible that you have never used the debugger?
As always definition matters.
perl -de0 is more than just a debugger.
... it's also Perl's main REPL, it's pretty good for ad hoc testing and interactive demos.
I use it regularly for that.
Others even use it as a Perl Shell, because it's very customizable.
Personally I almost never use it for debugging my own code ( i.e. Breakpoints, Watch-expressions, etc), because I have a unit-test mixed with debug output strategy (mostly Data::Dump 's dd and pp)
But it is very valuable when analyzing monolithic foreign code (e.g. B::Deparse)
Now perl -de0 is commonly known as "The Debugger" , which is causing reactions.
Unfortunately "people with strong opinions" here have a Pavlov reflex to demonstrate their ignorance.
| [reply] [d/l] [select] |
|
|
As always definition matters.
perl -de0 is more than just a debugger.
... it's also Perl's main REPL, it's pretty good for ad hoc testing and interactive demos.
I use it regularly for that.
I've seen your posts from (what are we gonna call it?) output in perl -de0 mode for years now, and they've mostly been over my head. Only recently have I discovered that I have a REPL too. I could have replicated your REPL.
Others even use it as a Perl Shell, because it's very customizable.
Can you elaborate?
But it is very valuable when analyzing monolithic foreign code (e.g. B::Deparse)
I would extend that to foreign code in general. I can't understand and integrate others' code into mine without it, whilst working alone. The number of keystrokes I save using the debugger is immeasurable. With successive use of save/source, it's like a trail in the forest and can even tell a story, and it's one you keep telling until you get out of the forest. I worked a little harder on a modifed script from bliako, and I'm able to point out places in code as perl -de0 sees it, and I can get into the nitty-gritty of execution. I'll repost the 2020 perl -de0 demonstration by Ricardo Signes, for reference. I place sources and debugger output in readmore tags:
Q1) What makes my Log4perl section a signature? This version is from parv, and I like that it gives me line numbers, but I don't see code for that. (?)
Q2) How would I turn the above script into "monolithic" foreign code?
Q3) Does Data::Roundtrip cover the same ground that JSON::XS did? I can't disambiguate what XS means.
Q4) What operator is this? I believe it takes my global value of 1 for $debug and makes it zero:
268==> $debug //= 0;
Q5) Finally, reading all around these issues, I found this one-liner and was wondering if this would fall under the umbrella of what "the debugger" might be. What is happening with this command?
$ perl -Mre=debug -e "/just|another|perl|hacker/"
Compiling REx "just|another|perl|hacker"
~ tying lastbr BRANCH (11) to ender END (15) offset 4
Final program:
1: TRIEC-EXACT[ahjp] (15)
<just>
<another>
<perl>
<hacker>
15: END (0)
stclass AHOCORASICKC-EXACT[ahjp] minlen 4
Freeing REx: "just|another|perl|hacker"
$
Thx for your comment
| [reply] [d/l] [select] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Now perl -de0 is commonly known as "The Debugger" , which is causing reactions.
Unfortunately "people with strong opinions" here have a Pavlov reflex to demonstrate their ignorance.
My personal Pavlov reflex kicks in when someone tries to save his own efforts on the cost of others.
Primarily with highly misspelled or misformatted text targeted to a larger audience.
But almost equally this is the case with examples given here that require an unnecessary effort to reproduce.
This includes "debugger sessions".
The simplest modifiable thing to reproduce is a runnable perl script.
Anything else I regard as laziness.
Greetings, -jo
$gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
| [reply] [d/l] |
|
|