Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Definition of empty {} after If() statement in eval{} statement

Tags:

perl

I am currently attempting to document a Perl script in preparation for converting it to .NET. I have no prior experience in Perl before now, however I was managing to get through it with a lot of Google-fu. I have run into a single line of code that has stopped me as I am unsure of what it does. I've been able to figure out most of it, but I'm missing a piece and I don't know if it's really that important. Here is the line of code:

eval { if(defined $timeEnd && defined $timeStart){}; 1 } or next;

I know that defined is checking the variables $timeEnd and $timeStart to see if they are null/nothing/undef. I also believe that the eval block is being used as a Try/Catch block to trap any exceptions. The line of code is in a foreach loop so I believe the next keyword will continue on with the next iteration of the foreach loop.

The part I'm having difficulty deciphering is the {};1 bit. My understanding is that the ; is a statement separator in Perl and since it's not escaped with a backslash, I have no idea what it is doing there. I also don't know what the {} means. I presume it has something to do with an array, but it would be an empty array and I don't know if it means something special when it is directly after an if() block. Lastly, I no idea what a single integer of 1 means and is doing there at the end of an eval block.

If someone could break that line of code down into individual parts and their definitions, I would greatly appreciate it.

Bonus: If you can give me a .NET conversion, and how each Perl bit relates to it, I will most certainly give you my internet respects. Here's how I would convert it to VB.NET with what I know now:

For each element in xmlList    'This isn't in the Perl code I posted, but it's the `foreach` loop that the code resides in.
    Try
        If Not IsNothing(timeEnd) AND Not IsNothing(timeStart) then 
        End If
    Catch ex as Exception
        Continue For
    End Try
Next
like image 556
вʀaᴎᴅᴏƞ вєнᴎєƞ Avatar asked Jan 07 '23 06:01

вʀaᴎᴅᴏƞ вєнᴎєƞ


1 Answers

Ignoring elsif and else clasuses, the syntax of an if statement is the following:

if (EXPR) BLOCK

The block is executed if the EXPR evaluates to something true. A block consists of a list of statements in curly braces. The {} in your code is the block of the if statement.

It's perfectly valid for blocks to be empty (to contain a list of zero statements). For example,

while (s/\s//) { }

is an inefficient way of doing

s/\s//g;

The thing is, the condition in the following has no side-effects, so it's quite useless:

if(defined $timeEnd && defined $timeStart){}

It can't even throw an exception![1] So

eval { if(defined $timeEnd && defined $timeStart){}; 1 } or next;

is equivalent to

eval { 1 } or next;

which is equivalent to[2]

1 or next;

which is equivalent to

# Nothing to see here...

  1. Technically, it can if the variables are magical.

    $ perl -MTie::Scalar -e'
       our @ISA = "Tie::StdScalar";
       tie(my $x, __PACKAGE__);
       sub FETCH { die }
       defined($x)
    '
    Died at -e line 4.
    

    I doubt the intent is to check for this.

  2. Technically, it also clears $@.

like image 154
ikegami Avatar answered Feb 12 '23 23:02

ikegami