I am adding on to another developers code, we are both new to perl I am trying to take a list of IPs and run it through whois. I am unsure how to access the data in the anonymous hash, how do I use it?
He told me the data was stored inside one. This is the only instance I could find mentioning a hash:
## Instantiate a reference to an anonymous hash (key value pair)
my $addr = {};
The anonymous hash is the {} part. It returns a reference which can be stored in a scalar variable, like in your example:
my $addr = {};
To see the structure, you can print it with Data::Dumper:
use Data::Dumper;
print Dumper $addr;
It might show you something like:
$VAR1 = {
'c' => 1,
'a' => 2
};
You access the hash keys using the arrow operator:
print $addr->{"a"}
Like how you would access a regular hash, but with the arrow operator in between.
You can dereference the reference by putting a hash sigil in front
%$addr
# compare %addr %$addr
# hash hashref dereferenced
Here is an anonymous hash:
my $anon_hash = {
key1 => 'Value 1',
key2 => 'Value 2',
key3 => 'Value 3',
}
If you want to access an individual value:
my $value = $anon_hash->{key1};
say $anon_hash->{key2};
If you want to update an individual value:
$anon_hash->{key3} = 'New value 3';
If you want to add a new key/value pair:
$anon_hash->{key4} = 'Value 4';
You can also use all of the standard hash functions (e.g. keys()). You just need to "deference" your hash reference - which means putting a '%' in front of it.
So, for example, to print all the key/value pairs:
foreach my $key (keys %$anon_hash) {
say "$key : $anon_hash->{$_}";
}
Related
Say I have an object alphabets and I want to set a couple of properties from another object like-
alphabets.a = data.a
alphabets.b = data.b
alphabets.c = data.c
Is there a way to remove the redundant usage of the variable alphabets and data?
UPDATE:
Assume that the properties have the same name. Now to remove the over use of property the variable reference data I can do the following
alphabets = (-> {aa, bb,cc}).call data
But the problem is that this will create a new object alphabets and what I want is that it should just add the properties to an already available object.
All you need to do is use the bracket notation of javascript, coupled with coffescript's for/of comprehension:
coffee> alphabets
{ a: '1', b: '2', c: '3' }
coffee> data = {}
{}
------> for k,v of alphabets # use Ctrl-V to get the multiline prompt
....... data["#{k}#{k}"] = v
[ '1', '2', '3' ]
coffee> data
{ aa: '1', bb: '2', cc: '3' }
coffee>
I am looing for information on google about declaring array in expect but unable to find it.even the witki link for the line is empty.
I know i can set array values like set arr("hh") "hhh" but how do i declare it.
and can i print the whole array using one command or do i have to loop through it to print all the elements.
Or there is no such thing as declaring array in expect/tcl.i mean can we access any array
just by using global keyword.
You don't have to declare an array, but if you want to:
array set variableName {}
The last word is an empty list. If you have some default values you want to store in the array, you can say:
array set varname {key1 val1 key2 val2 ... ...}
If you're curious, here's how parray is implemented:
proc parray {a {pattern *}} {
upvar 1 $a array
if {![array exists array]} {
error "\"$a\" isn't an array"
}
set maxl 0
set names [lsort [array names array $pattern]]
foreach name $names {
if {[string length $name] > $maxl} {
set maxl [string length $name]
}
}
set maxl [expr {$maxl + [string length $a] + 2}]
foreach name $names {
set nameString [format %s(%s) $a $name]
puts stdout [format "%-*s = %s" $maxl $nameString $array($name)]
}
}
You don't declare arrays in Expect (or Tcl in general) you just use them.
But arrays and other variables do have scope. If you are in a proc and want to
refer to an array arr which has global scope you can either say global arr before
using it or prefix the name with :: each time you use it, eg. set ::arr(hh) "hhh"; puts $::arr(hh).
There is a command parray to print a whole array, but this is loaded from library scripts rather than being built-in, so may not be available depending on how your Expect installation has been done. Eg.
expect1.1> set arr(a) ACBD
ACBD
expect1.2> set arr(b) "BBB bbb"
BBB bbb
expect1.3> parray arr
arr(a) = ACBD
arr(b) = BBB bbb
I see some people using hash(es) like this:
end_points = { "dev" => "http://example.com"}
and in other places using this:
end_points = { :dev => "http://example.com"}
What is the difference between these two approaches?
"" declares a String. : declares a Symbol. If you're using a hash, and you don't need to alter the key's value or keep it around for anything, use a symbol.
Check this out for a more elaborate explanation.
:dev is a Symbol, 'dev' is a String.
Most of the time, symbols are used but both are correct. Some read on the subject :
What are symbols and how do we use them?
Why use symbols as hash keys in Ruby?
In first case you use string in second you use symbol. Symbols are specific type in Ruby. In whole program there is only one instance of symbol, but string can have it many. I.e.
> :sym.__id__
=> 321608
> :sym.__id__
=> 321608
> "sym".__id__
=> 17029680
> "sym".__id__
=> 17130280
As you see symbol always has the same ID what mean that it is always the same object, but string is every time new string in new place of memory. That's the case why symbols are more common as hash keys, it's simply faster.
#!perl6
use v6;
my $list = 'a' .. 'f';
sub my_function( $list ) {
for ^$list.elems -> $e {
$list[$e].say;
}
}
my_function( $list );
First I tried this in perl5-style, but it didn't work:
for #$list -> $e {
$e.say;
}
# Non-declarative sigil is missing its name at line ..., near "#$list -> "
How could I do this in perl6?
You don't dereference variables like this in Perl 6. Just use for $list
But that proably won't do what you want to do. 'a'..'f' doesn't construct a list in Perl 6, but rather a built-in data type called Range. You can check that with say $list.WHAT. To turn it into a list and iterate over each element, you'd use for $list.list
These should work:
.say for #( $list );
.say for $list.list;
.say for $list.flat;
Since $listis a scalar, for $list will just iterate over a single item.
Now, Rakudo 2015.02 works it ok.
You'd better use # as twigil of variable name as array.
Perl 6 is context sensitive language, so if you want array act as 'true array', you'd better give it a suitable name.
#!perl6
use v6;
my #list = 'a' .. 'f';
for #list -> $e { $e.say };
I've seen the # symbol used in PowerShell to initialise arrays.
What exactly does the # symbol denote and where can I read more about it?
In PowerShell V2, # is also the Splat operator.
PS> # First use it to create a hashtable of parameters:
PS> $params = #{path = "c:\temp"; Recurse= $true}
PS> # Then use it to SPLAT the parameters - which is to say to expand a hash table
PS> # into a set of command line parameters.
PS> dir #params
PS> # That was the equivalent of:
PS> dir -Path c:\temp -Recurse:$true
PowerShell will actually treat any comma-separated list as an array:
"server1","server2"
So the # is optional in those cases. However, for associative arrays, the # is required:
#{"Key"="Value";"Key2"="Value2"}
Officially, # is the "array operator." You can read more about it in the documentation that installed along with PowerShell, or in a book like "Windows PowerShell: TFM," which I co-authored.
While the above responses provide most of the answer it is useful--even this late to the question--to provide the full answer, to wit:
Array sub-expression (see about_arrays)
Forces the value to be an array, even if a singleton or a null, e.g. $a = #(ps | where name -like 'foo')
Hash initializer (see about_hash_tables)
Initializes a hash table with key-value pairs, e.g.
$HashArguments = #{ Path = "test.txt"; Destination = "test2.txt"; WhatIf = $true }
Splatting (see about_splatting)
Let's you invoke a cmdlet with parameters from an array or a hash-table rather than the more customary individually enumerated parameters, e.g. using the hash table just above, Copy-Item #HashArguments
Here strings (see about_quoting_rules)
Let's you create strings with easily embedded quotes, typically used for multi-line strings, e.g.:
$data = #"
line one
line two
something "quoted" here
"#
Because this type of question (what does 'x' notation mean in PowerShell?) is so common here on StackOverflow as well as in many reader comments, I put together a lexicon of PowerShell punctuation, just published on Simple-Talk.com. Read all about # as well as % and # and $_ and ? and more at The Complete Guide to PowerShell Punctuation. Attached to the article is this wallchart that gives you everything on a single sheet:
You can also wrap the output of a cmdlet (or pipeline) in #() to ensure that what you get back is an array rather than a single item.
For instance, dir usually returns a list, but depending on the options, it might return a single object. If you are planning on iterating through the results with a foreach-object, you need to make sure you get a list back. Here's a contrived example:
$results = #( dir c:\autoexec.bat)
One more thing... an empty array (like to initialize a variable) is denoted #().
The Splatting Operator
To create an array, we create a variable and assign the array. Arrays are noted by the "#" symbol. Let's take the discussion above and use an array to connect to multiple remote computers:
$strComputers = #("Server1", "Server2", "Server3")<enter>
They are used for arrays and hashes.
PowerShell Tutorial 7: Accumulate, Recall, and Modify Data
Array Literals In PowerShell
I hope this helps to understand it a bit better.
You can store "values" within a key and return that value to do something.
In this case I have just provided #{a="";b="";c="";} and if not in the options i.e "keys" (a, b or c) then don't return a value
$array = #{
a = "test1";
b = "test2";
c = "test3"
}
foreach($elem in $array.GetEnumerator()){
if ($elem.key -eq "a"){
$key = $elem.key
$value = $elem.value
}
elseif ($elem.key -eq "b"){
$key = $elem.key
$value = $elem.value
}
elseif ($elem.key -eq "c"){
$key = $elem.key
$value = $elem.value
}
else{
Write-Host "No other value"
}
Write-Host "Key: " $key "Value: " $value
}