Reputation: 794
I have the following in the perl code:
$art_entities->{$rel_art_path}++;
I see that it is a post increment on a hash, how does it work? What would be something similar in Java or C#?
Upvotes: 1
Views: 2886
Reputation: 386331
It creates an element in the hash if it doesn't exist, then increments its value by one[1].
For example,
my %counts;
++$counts{$_} for split(//, 'abracadabra');
produces
my %counts = (
a => 5,
b => 2,
c => 1,
d => 1,
r => 2,
);
It's also useful for filtering out duplicates. For example,
my %seen;
my @uniq = grep !$seen{$_}++, split(//, 'abracadabra');
produces
my @uniq = qw( a b r c d );
Perl:
my %dict;
++$dict{$key}; # $dict{$key}++ in scalar context gets optimized into ++$dict{$key}.
C#:
Dictionary<string, int> dict = new Dictionary<string, int>();
int i;
dict.TryGetValue(key, out i);
dict[key] = i+1;
C#:
Dictionary<string, int> dict = new Dictionary<string, int>();
if (dict.ContainsKey(key))
++dict[key];
else
dict[key] = 1;
Java:
Map<String, Integer> dict = new HashMap<String, Integer>();
Integer i = dict.get(key);
if (i == null) {
map.put(key, 1);
} else {
map.put(key, i+1);
}
++
has some "magical" behaviour if the variable being incremented contains a string (incrementing a
into b
, for example), but I don't think that's relevant here.Upvotes: 4
Reputation: 6553
The ++
operator returns the value and then increments the variable by one. Hashes are just unordered collections of scalar values indexed by their associated string key; incrementing a scalar in a hash is no different from incrementing a scalar outside of a hash.
The following are functionally equivalent:
$hash{foo}++;
$hash_ref->{foo}++;
$foo++;
There's a little extra magic built in to Perl's auto-increment operator, though:
If you increment a variable that is numeric, or that has ever been used in a numeric context, you get a normal increment. If, however, the variable has been used in only string contexts since it was set, and has a value that is not the empty string and matches the pattern
/^[a-zA-Z]*[0-9]*\z/
, the increment is done as a string, preserving each character within its range, with carry:print ++($foo = "99"); # prints "100" print ++($foo = "a0"); # prints "a1" print ++($foo = "Az"); # prints "Ba" print ++($foo = "zz"); # prints "aaa"
undef
is always treated as numeric, and in particular is changed to0
before incrementing (so that a post-increment of an undef value will return0
rather thanundef
).
Java and C# both have increment operators, but as far as I know, they're not nearly as magical as Perl's. Java's HashMap
provides get()
and put()
methods, so you don't get direct access to the underlying data:
map.put(key, map.get(key) + 1);
C# collections use square brackets, so if you had a Dictionary
, for example:
dict["foo"]++;
Upvotes: 4
Reputation: 8663
$art_entities->{$rel_art_path}++;
$art_entities
is a variable (a scalar, see the leading $
sign). With the arrow syntax, it looks like it is an object.
$rel_art_path
is another scalar variable.
->{...}
accesses a field (right side of the arrow, in {curly braces}) from the object on the left side of the arrow. Perl does not do much in terms of access limitations, i.e., there is no public
, private
, or protected
. You could add your own code to enforce private
access (see Perl Best Practices) or use a class framework like Moose.
The code uses the value of $rel_art_path
as a field name in the $art_entities
object.
In Java, this would be done with reflection:
import java.lang.reflect.Field;
public class SomeClass {
public static void main(String[] args) throws Exception {
SomeOtherClass soc = new SomeOtherClass();
doSomething(soc, "someValue");
soc.print();
}
public static void doSomething(Object art_entities, String rel_art_path)
throws Exception {
Class<?> c = art_entities.getClass();
Field field = c.getDeclaredField(rel_art_path);
field.setInt(art_entities, field.getInt(art_entities) + 1);
}
}
class SomeOtherClass {
public int someValue = 0;
public void print() {
System.out.println("my value is " + someValue);
}
}
(I've used your variable names in the Java code to make it clearer which corresponds to which. Obviously they are Perl style (using underscores), not Java (camel case).)
In Java, this is hackish and quite a lot to write, in Perl it's short and normal.
Upvotes: -1