Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

How to merge the given snippet of code into the below functionality.

by vlearner (Initiate)
on Feb 03, 2022 at 17:02 UTC ( [id://11141110]=perlquestion: print w/replies, xml ) Need Help??

vlearner has asked for the wisdom of the Perl Monks concerning the following question:

May be a silly question to ask from my side but I need help in this. The snippet of code below is taking permission from command prompt whether to remove the <alt> tag or not.
print "do you want to remove <alt> tags Y/N \n"; chomp(my $ok = <>), my $yes = 'y'; my $no = 'n'; $inp = lc($ok); if ($inp eq $yes){ print "removed <alt>"; } elsif ($inp eq $no) { print "not removed <alt>"; }
The function with which I want to merge is this:
sub RemoveAltTag($) { my $doc = shift; ############################## my $cnt = 0; my $nodes = $doc->getElementsByTagName("image"); for(my $i = 0;$i < $nodes->getLength(); $i++) { my $kids = $nodes->item($i)->getChildNodes(); for(my $k =0; $k < $kids->getLength(); $k++) { if($kids->item($k)->toString() =~ /<alt>/i) { $nodes->item($i)->removeChild($kids->item($k)); print "\n Removed <alt> tag" if $VERBOSE; $cnt++ } } } return $cnt;
kindly help me with this.

Replies are listed 'Best First'.
Re: How to merge the given snippet of code into the below functionality.
by kcott (Archbishop) on Feb 03, 2022 at 20:34 UTC

    G'day vlearner,

    In the examples below, I've used perle, a common alias of mine, to report problems.

    $ alias perle alias perle='perl -Mstrict -Mwarnings -Mautodie=:all -MCarp::Always -E +'

    As a bare minimum, your code should include the strict and warnings pragmata. See "Perl introduction for beginners: Safety net".

    There are a variety of issues with the code you posted: some major; some minor; some future gotchas. I'll work through those (mostly) in the order in which they appear.

    chomp(my $ok = <>),

    Terminate statements with a semicolon, not a comma.

    $ perle 'print "Query (Y/N): "; chomp(my $in = <>), say $in;' Global symbol "$in" requires explicit package name (did you forget to +declare "my $in"?) at -e line 1. Execution of -e aborted due to compilation errors. at -e line 1.

    Code that you post here — even test code — should work, so that we don't have to debug it first. The only exception would be code that you can't fix; in which case, it should be accompanied with exception messages. A good place to start is "perl -c" for a syntax check; but do note that it is just a starting point:

    $ perl -MO=Deparse -e 'chomp(my $in = <>), say $in;' chomp(my $in = readline ARGV), $in->say; -e syntax OK
    print "do you want to remove <alt> tags Y/N \n";

    Allow the user to respond immediately after, not underneath, the prompt. Just remove \n to fix.

    my $ok = <>

    Use <STDIN> instead of <>. Compare these:

    # This dies: $ perle 'print "Query (Y/N): "; chomp(my $in = <>); say $in;' some_arg Can't open some_arg: No such file or directory at -e line 1. Use of uninitialized value $in in chomp at -e line 1. Use of uninitialized value $in in say at -e line 1. Query (Y/N): # This allows input: $ perle 'print "Query (Y/N): "; chomp(my $in = <STDIN>); say $in;' som +e_arg Query (Y/N): y y
    print "do you want to remove <alt> tags Y/N \n"; chomp(my $ok = <>), my $yes = 'y'; my $no = 'n';

    The prompt uses uppercase; the code afterwards uses lowercase. Be consistent to improve readability.

    $inp =

    Don't use package variables; use lexical variables. In this instance, $inp is not needed (see below).

    lc($ok)

    Prefer fc() — see that documentation for details. You'll need Perl v5.16 for this: "perl5160delta: New function fc and corresponding escape sequence \F for Unicode foldcase".

    if ($inp eq $yes) {...} elsif ($inp eq $no) {...}

    This is a problem unless your users have keyboards with only the two letters "Y" and "N". :-)

    if (fc($ok) eq fc($yes)) { print "Removing ...\n"; RemoveAltTag($some_doc_variable); } else { print "No removal.\n"; }
    sub RemoveAltTag($)

    Unless you know what you're doing, and why you're doing it, don't use prototypes. See "perlsub: Prototypes" for details.

    my $doc = shift;

    Consider future-proofing your code with: 'my ($doc) = @_;'. For many years, I fell into the trap of writing 'my $param1 = shift;'; then later, adding another parameter, and ending up with 'my ($param1, $param2) = shift;' which, if I recall, was often a difficult bug to track down.

    for(my $i = 0;$i < $nodes->getLength(); $i++)

    This form of for often results in off-by-one errors. It's less typing, clearer code, less error-prone, and more Perlish, to use this form:

    for my $i (0 .. $end) { ... }

    — Ken

Re: How to merge the given snippet of code into the below functionality.
by hippo (Bishop) on Feb 03, 2022 at 17:10 UTC
    RemoveAltTag ($foo) if $inp eq $yes;

    🦛

Re: How to merge the given snippet of code into the below functionality.
by Fletch (Bishop) on Feb 03, 2022 at 18:02 UTC

    Rather than rolling your own interaction routine you might try IO::Prompter or IO::Prompt from CPAN.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: How to merge the given snippet of code into the below functionality.
by davido (Cardinal) on Feb 04, 2022 at 04:17 UTC

    Something like this ought to work, though if it were me I would prefer providing the user with some context if I'm going to prompt them to remove an <alt> tag.

    use IO::Prompt::Tiny q(prompt); sub remove_ok { my $prompt = 'Do you want to remove <alt> tags? (y/n)'; my $default = 'n'; my $resp = ''; while ($resp !~ m/^[yn]/i) { $resp = prompt($prompt, $default); } return $resp =~ m/^y/i; } sub RemoveAltTag { my $doc = shift; my $cnt = 0; my $nodes = $doc->getElementsByTagName("image"); for(my $i = 0;$i < $nodes->getLength(); $i++) { my $kids = $nodes->item($i)->getChildNodes(); for(my $k =0; $k < $kids->getLength(); $k++) { if( $kids->item($k)->toString() =~ /<alt>/i && remove_ok() ) { $nodes->item($i)->removeChild($kids->item($k)); print "\n Removed <alt> tag" if $VERBOSE; $cnt++ } } } return $cnt; }

    But again, you might want to show some of the surrounding context so that the user can use that information in deciding what to remove.


    Dave

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11141110]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (5)
As of 2024-04-25 08:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found