I want add the variable $hostname in the variable $hostame_table appended with _table.
My code:
use Sys::Hostname ();
my $hostname = Sys::Hostname::hostname();
my $hostname_table = "$hostname"+"_table";
print "$hostname_table";
I would like the result to be computername_table.
What you're looking for here is called "string concatenation". Perl uses a dot (.) as the concatenation operator, not the + which you've tried to use.
$hostname_table = $hostname . '_table';
print $hostname_table;
Update: Another common approach would be to just "interpolate" the values in a double-quoted string.
$hostname_table = "$hostname_table"; # This doesn't work.
Unfortunately, this simple approach doesn't work here as "_table" is valid as part of a variable name and, therefore, Perl doesn't know where your variable name ends. You can get around that by using a slightly more complex syntax which wraps the variable name in { ... }.
$hostname_table = "${hostname}_table";
Related
Is this a way of using a one-liner to assign an array value to a variable using the split function.
I have the following code. This works.
my #Fields = split(',',#_[0]);
my $Unit = #Fields[2];
Wondering if it could be written in one like the following, they are returning syntax errors.
my $Unit = split(',',#_[0])[2];
my $Unit = #(split(',',#_[0]))[2];
Your second one is very close. Drop that leading #:
my $Unit = (split(',', $_[0]))[2];
(Note $_[0] instead of the one-element array slice #_[0]... if you have use warnings; in effect like you should, that would give you one.)
I have a string "/Name Pa$Name#my"
$myname = GetContent("Name")
GetContent is only gets the key and gives the value for that Key. I cannot modify the GetContent function.
If i execute above, as "Pa$Name#my" contains the '$' char, $myname gives me value as "Pa#my" and ignores "$Name" content.
What can i do to get the $myname = Pa$Name#my ? Can i append some special characters while assigning the $myname variable.
As far as I understand your trouble comes from the fact that the var $name does not exist. You can use single qotes if you don't want Powershell to look for vars :
$a = 'Pa$Name#my'
Hi I am writing a perl script to accomplish some task.In my script I am using one if loop to compare two strings as shown below.
if($feed_type eq "SE"){
...........}
The above code is not giving me any warning but the output is not as I expected.
Instead of 'eq' if I use '=' I am getting a warning saying expectng '==' but '=' is present. But I am getting the expected output.
Ideally for string comparison I must use 'eq' and for numbers '=='. In this case it's not working. Can anyone figure out what is the problem here?
More info:
This if loop is present in a subroutine. $feed_type is an input for this subroutine. I am reading the input as below:
my $feed_type=#_;
The problem is fixed. I just changed the assignemet statement of feed_type as below
my $feed_type=$_[0];
and it's reading the value as SE and the code is working.
but I still dont know why my $feed_type=$_[0]; didn't work.
= might well work in place of eq, but not for the reason you think.
#!/usr/bin/env perl
use strict;
use warnings;
my $test = "fish";
my $compare = "carrot";
if ( $test = $compare ) {
print "It worked\n";
}
Of course, the problem is - it'll always work, because you're testing the result of an assignment operation.*
* OK, sometimes assignment operations don't work - this is why some coding styles suggest testing if ( 2 == $result ) rather than the other way around.
This is about a core Perl concept: Context. Operators and functions work differently depending on context. In this case:
my $feed_type = #_;
You are assigning an array in scalar context to the variable. An array in scalar context returns its size, not the elements in it. For this assignment to work as you expect, you have to either directly access the scalar value you want, like you have suggested:
my $feed_type = $_[0];
...or you can put your variable in list context by adding parentheses:
my ($feed_type) = #_;
This has the benefit of allowing you to perform complex assignments, like this:
my ($first, $second, #rest) = #_;
So, in short, the problem was that your comparison that looked like this:
if($feed_type eq "SE")
Was actually doing this:
if(1 eq "SE")
And returning false. Which is true. Consider this self-documenting code:
sub foo {
my $size = #_;
if ($size == 1) {
warn "You passed 1 argument to 'foo'\n";
return;
}
}
Which demonstrates the functionality you inadvertently used.
= is used to assign the variable a value, so you would need '==' to compare numerical values and 'eq' for strings.
If it's complaining about not using '==', then it's because $feed_type is not a string.
I can't tell as there's no more code. Whatever $feed_type is set by you need to confirm it actually contains a string or if you're even referencing it correctly.
OK, I've looked hard and have tried a myriad of variations to get this to work. I need some help from the perl experts.
First of all, I know, I know, don't use dynamic variable names! Well, I think I need to do so in this case. I'm fixing an inherited script. It has a set of variables that are formed with prefix + "_" + suffix. This started small, but prefix is now a list of about 20 and suffix of about 50 -- a thousand different variables.
The script in some cases loops over these variables, using eval to retrieve an individual value, etc.. This all works. The problem is, all uses of the different variables throughout the script, whether inside a loop on the prefix and/or suffix or just a hardcoded use, assume that these variables are globalized by using use var qw($varname). The number of use vars hardcoded statements has grown out of control. Moreover, there are thousands of past input profile files that initialize these variables using global syntax, all of which need to continue to work.
I was hoping I could improve maintainability by doing the globalization step in a loop, dynamically creating the variable names one at a time, then globalizing them with use vars or our. Here is some code to show what I'm after. I've shown several options here, but each is actually a separate trial. I have tried other variations and cannot keep them straight anymore.
my #prefixes = ("one", "two", ..., "twenty");
my #suffixes = ("1", "2", ..., "50");
my $globalvars = "";
for my $suffix (#suffixes) {
for my $prefix (#prefixes) {
# option 1 -- remainder of #1 outside of loop
# NOTE: 1.a (no comma); 1.b (include comma between vars)
$globalvars .= "\$$prefix\_$suffix, ";
# option 2
eval "use vars qw(\$$prefix\_$suffix)";
# option 3
my $g = "$prefix\_$suffix";
eval ("use vars qw(\$$g)");
# option 4
eval ("our \$$g");
}
}
# option 1.a
use vars qw($globalvars);
# or option 1.b
my (eval "$globalvars");
:
:
:
# now use them as global variables
if ($one_1 eq ...) {
if ($one_10) {
It seems that the problem with "use vars" (besides the fact that it is discouraged) is that the string inside qw has to be the actual variable name, not a dynamic variable name. The 'eval' options don't work, I think, because the scope only exists within the eval itself.
Is there a way to do this in perl?
string inside qw has to be the actual variable name, not a dynamic variable name
That's how qw works, it quotes words, it does no interpolation. You don't have to use qw with use vars, though.
#! /usr/bin/perl
use warnings;
use strict;
my #global_vars;
BEGIN { #global_vars = qw($x $y) }
use vars #global_vars;
# strict won't complain:
$x = 1;
$y = 2;
BEGIN is needed here, because use vars runs in compile time, and we need #global_vars to be already populated.
There's no need for eval EXPR since there's no need to use qw. qw is just one way to create a list of strings, and one that's not particularly useful to your needs.
my #prefixes; BEGIN { #prefixes = qw( one two ... twenty ); }
my #suffixes; BEGIN { #suffixes = 1..50; }
use vars map { my $p = $_; map { '$'.$p.'_'.$_ } #suffixes } #prefixes;
I've got the following Perl code:
my $wantedips;
# loop through the interfaces
foreach (#$interfaces) {
# local variable called $vlan
my $vlan = $_->{vlan};
# local variable called $cidr
my $cidr = $_->{ip} ."/".$nnm->bits();
# I dont understand this next bit.
# As a rubyist, it looks like a method called $cidr is being called on $wantedips
# But $cidr is already defined as a local variable.
# Why the spooky syntax? Why is $cidr passed as a method to $wantedips?
# what does ->{} do in PERL? Is it some kind of hash syntax?
$wantedips->{$cidr} = $vlan;
# break if condition true
next if ($ips->{$cidr} == $vlan);
# etc
}
The part I don't get is in my comments. Why is $cidr passed to $wantedips, when both are clearly defined as local variables? I'm a rubyist and this is really confusing. I can only guess that $xyz->{$abc}="hello" creates a hash of some sort like so:
$xyz => {
$abc => "hello"
}
I'm new to Perl as you can probably tell.
I don't understand why you are comfortable with
my $vlan = $_->{vlan}
but then
$wantedips->{$cidr} = $vlan
gives you trouble? Both use the same syntax to access hash elements using a hash reference.
The indirection operator -> is used to apply keys, indices, or parameters to a reference value, so you access elements of a hash by its reference with
$href->{vlan}
elements of an array by its reference with
$aref->[42]
and call a code reference with
$cref->(1, 2, 3)
As a convenience, and to make code cleaner, you can remove the indirection operator from the sequences ]->[ and }->{ (and any mixture of brackets and braces). So if you have a nested data structure you can write
my $name = $system->{$ip_address}{name}[2]
instead of
my $name = $system->{$ip_address}->{name}->[2]
#I dont understand this next bit.
$wantedips->{$cidr} = $vlan;
$wantedips is a scalar, specifically it is a hashref (a reference to a hash).
The arrow gets something from inside the reference.
{"keyname"} is how to access a particular key in a hash.
->{"keyname"} is how you access a particular key in a hash ref
$cidr is also a scalar, in this case it is a string.
->{$cidr} accesses a key from a hash ref when the key name is stored in a string.
So to put it all together:
$wantedips->{$cidr} = $vlan; means "Assign the value of $vlan to the key described by the string stored in $cidr on the hash referenced by $wantedips.
I can only guess that $xyz->{$abc}="hello" creates a hash of some sort
like.
Let's break this down to a step by step example that strips out the loops and other bits not directly associated with the code in question.
# Create a hash
my %hash;
# Make it a hashref
my $xyz = \%hash;
# (Those two steps could be done as: my $xyz = {})
# Create a string
my $abc = "Hello";
# Use them together
$xyz->{$abc} = "world";
# Look at the result:
use Data::Dump;
Data::Dump::ddx($xyz);
# Result: { Hello => "world" }