in reply to showing the error ,Can't modify concatenation (.) or string in scalar assignment

G'day gayu_justin,

Firstly, this code is highly confusing and a potential source of errors:

my $check_ = "chck"; my $chck_ = "check";

Regarding the code generating the error, instead of:

foreach $usr( @ #print $usr . "\n"; #print $check_.$usr; my $check_.$usr = $cgi->param("$chck_.$usr"); print $chck_.$usr; }

I suspect you want something closer to this (untested):

for my $user_id (@userchecklist_id) { my $checkbox_name = "check_$user_id"; my $checkbox_value = $cgi->param($checkbox_name); print "Checkbox name: $checkbox_name\n"; print "Checkbox value: $checkbox_value\n"; }

By using meaningful variable names and taking a little care when laying out your code, you'll improve readability and maintainability. Take a look at perlstyle for some tips on the latter.

As a final point, note how you've reused $usr:

my $usr = $user->id; ... foreach $usr( @userchecklist_id) {

This, again, is a potential source of errors. Consider what might happen if you wanted to use the $user->id version of $usr after the loop. By using my when you start the loop (as I did) you get a different variable (scoped to the loop) and avoid possible future problems. [In case you didn't know, for and foreach are synonymous so you can save yourself some typing (see perlsyn - Foreach Loops).]

-- Ken

Replies are listed 'Best First'.
Re^2: showing the error ,Can't modify concatenation (.) or string in scalar assignment
by AnomalousMonk (Archbishop) on Jul 18, 2013 at 10:43 UTC

    The following is more for the benefit gayu_justin than for kcott:

    Consider what might happen if you wanted to use the $user->id version of $usr after the loop. By using my when you start the loop (as I did) you get a different variable (scoped to the loop) and avoid possible future problems.

    This is an oddity, IMHO, of the way for-loop variables behave. The variable is fully localized even though it is lexical. So this code doesn't work as one (I myself, on more than one occasion) would naively expect:

    >perl -wMstrict -le "my $max_x = 99; ;; for $max_x (0 .. 5) { print $max_x; last if $max_x == 2; } ;; print qq{max_x: $max_x}; " 0 1 2 max_x: 99

    Nor does the loop variable do something really odd like becoming a package variable:

    >perl -wMstrict -le "my $x = 'foo'; print qq{x before loop: '$x'}; ;; for $x (0 .. 2) { func(); our $y; print qq{$x, $y}; } ;; print qq{x after loop: '$x'}; sub func { our $x; our $y; $x = 99; $y = 42; } " x before loop: 'foo' 0, 42 1, 42 2, 42 x after loop: 'foo'

    So what's the point of ever using a lexical loop variable in the  for my $x (...) { ... } form? If  $x was a package variable to start with, the loop variable  $x would then be fully lexically scoped. Remove the  my from the following example to see the difference.

    >perl -wMstrict -le "our $max_x = 99; ;; for my $max_x (0 .. 4) { func(); print $max_x; last if $max_x == 2; } ;; print qq{max_x after loop: $max_x}; ;; sub func { $max_x = 42; } " 0 1 2 max_x after loop: 42

      ++ You're absolutely right. I've been writing for my $var ... for so long that I'd forgotten about that rather unintuitive behaviour.

      By the way, you're not the only one to have been bitten by that. :-)

      -- Ken