3

I was trying to write a small perl script to understand Getopt::Long.

Below is the script:

#!/usr/bin/perl

use strict;
use Getopt::Long;

my $op_type = "";
my @q_users;

GetOptions (
  'query' => $op_type = "query",
  'create' => $op_type = "create",
  'modify' => $op_type = "modify",
  'delete' => $op_type = "delete",
  'user=s' => \@q_users
) or usage ("Invalid options.");

print "operation : $op_type\n";

When i ran this script as shown below:

$ ./all_opt.pl --query
operation : delete

I am assuming that am missing some kind of break statment in my program. I was expecting operation : query as the result.

Please let me know what i am missing here.

Fazlin
  • 2,285
  • 17
  • 29

2 Answers2

5

You were very close, but I think you slightly misread the Getopt::Long documentation. Any code that you want to run when an option is found needs to be in a subroutine.

#!/usr/bin/perl

use strict;
use Getopt::Long;

my $op_type = "";
my @q_users;

GetOptions (
  'query'  => sub { $op_type = 'query' },
  'create' => sub { $op_type = 'create' },
  'modify' => sub { $op_type = 'modify' },
  'delete' => sub { $op_type = 'delete' },
  'user=s' => \@q_users
) or usage ("Invalid options.");

print "operation : $op_type\n";

Note that I've just added sub { ... } around your existing $op_type = '...' code.

Dave Cross
  • 68,119
  • 3
  • 51
  • 97
  • Thanks it worked. Yes i missed this part of the documentation. – Fazlin Aug 09 '16 at 09:25
  • 2
    @Fazlin the `sub { ... }` creates what we call a _code reference_ in Perl, or an _[anonymous function](https://en.wikipedia.org/wiki/Anonymous_function)_ or _lambda function_ in more general terms. It's basically _here is some code, you can run that when you want_. It does not get executed when those lines are encountered. – simbabque Aug 09 '16 at 09:29
4

Explanation of what your code does

You are misunderstanding the syntax. Let's add some parenthesis to clarify how Perl sees this code.

GetOptions(
  'query'  => ( $op_type = "query"  ),
  'create' => ( $op_type = "create" ),
  'modify' => ( $op_type = "modify" ),
  'delete' => ( $op_type = "delete" ),
  'user=s' => \@q_users
) or usage ("Invalid options.");

It will first run the assignment operations inside the parens. Each of those return the value that is assigned to $op_type.

$ perl -e 'print $foo = "bar"'
bar

Since all of them assign something to the same variable, the code is identical to this code.

GetOptions(
  'query'  => "query",
  'create' => "create",
  'modify' => "modify",
  'delete' => "delete",
  'user=s' => \@q_users
) or usage ("Invalid options.");
$op_type = "delete";

GetOptions wants you to pass references to variables so it can assign values to the variables for you. But you are doing that only for user with \@q_users. The rest of them is just strings.

In the end, you are printing the value of $op_type, which always has the value of the last assignment. As we saw above, that's delete. It cannot be anything else, because GetOptions never gets a reference to $op_type, so it cannot assign.

simbabque
  • 53,749
  • 8
  • 73
  • 136