Re: Assign method call to hash value?

2013-01-30 Thread David Cantrell
On Tue, Jan 29, 2013 at 09:12:38PM +, Daniel Perrett wrote:
 =head1 TANGENT
 
 ... about the design of context in perl.
 
 I get how you can do things like {%original, %changes}, but is there a
 reason why the = couldn't add some magic and assume scalar context on
 whatever it precedes? The only case I imagine it would break would be
 a hypothetical {%original,  key= @odd_list }, but I don't know why
 anyone would do that.

Perhaps it would be nice if it had been like that right from the start,
but ...

http://grep.cpan.me/?q=%3D%3E+%40

-- 
David Cantrell | London Perl Mongers Deputy Chief Heretic

PLEASE NOTE: This message was meant to offend everyone equally,
regardless of race, creed, sexual orientation, politics, choice
of beer, operating system, mode of transport, or their editor.


Re: Assign method call to hash value?

2013-01-29 Thread Yitzchak Scott-Thoennes
On Mon, Jan 28, 2013 at 7:39 PM, Sam Kington s...@illuminated.co.uk wrote:

 I forget when the use of variables as method names - for the $r-$_ bit - was 
 introduced; it was probably perl 5.6.0, but it might be as late as 5.8.0. 
 Either way, it should be safe for all but paleolithic environments.

As far as I know it was in 5.000; certainly it was in 5.003 at least.


Re: Assign method call to hash value?

2013-01-29 Thread gvim

On 29/01/2013 02:33, Mike Stok wrote:

Have you tried reading

   perldoc -f scalar

Hope this helps,

Mike



Yes, I'm aware of the scalar function but still not clear why assigning 
$r-method as a hash value doesn't invoke a scalar context in the first 
place.


gvim


Re: Assign method call to hash value?

2013-01-29 Thread Jasper
On 29 January 2013 11:36, gvim gvi...@gmail.com wrote:

 Yes, I'm aware of the scalar function but still not clear why assigning
 $r-method as a hash value doesn't invoke a scalar context in the first
 place.


Is there any context in the braces? It's just a (albeit fat) comma
separated list of stuff, isn't it?


-- 
Jasper


Re: Assign method call to hash value?

2013-01-29 Thread Peter Corlett
On Tue, Jan 29, 2013 at 11:36:21AM +, gvim wrote:
[...]
 Yes, I'm aware of the scalar function but still not clear why assigning
 $r-method as a hash value doesn't invoke a scalar context in the first
 place.

Because creating an anonymous hash with { ... } imposes list context on its
contents. If it didn't, you wouldn't be able to, for example, conveniently do
$foo = { %$bar, blargh = 1 } to copy a hash while changing one key.



Re: Assign method call to hash value?

2013-01-29 Thread gvim

On 29/01/2013 03:39, Sam Kington wrote:

As Mike mentioned, you almost certainly want to say { ... valid = scalar 
$r-valid, ... } instead; checking the documentation for Data::FormValidator and 
seeing what it says the missing, valid and unknown methods return in list context vs 
scalar context, might help.

https://metacpan.org/module/Data::FormValidator#check- says It returns its results 
as a Data::FormValidator::Results object and e.g. the documentation for the missing 
method says


In an array context it returns the list of fields which are missing. In a 
scalar context, it returns an array reference to the list of missing fields.

If called with an argument, it returns true if that field is missing, undef 
otherwise.


So you could replace the last 5 lines of your sub with e.g.

 return {
 passed  = $passed,
 valid   = scalar $r-valid,
 missing = scalar $r-missing,
 invalid = scalar $r-invalid,
 unknown = scalar $r-unknown,
 };

Once written like that, it becomes clear that there's some repetition going on.

There's two things you could do at this point. Depending on what you need to do 
later on, you might just say

 return { passed = $passed, form_validator_results = $r };

and let the calling code fish out the stuff it needs. This might be mildly more 
efficient if it ever turns out that calling the valid, missing, invalid and 
unknown methods ahead of time was wasteful if the calling code didn't need that 
information. Or it might not; benchmark your code, if performance is a problem, 
with Devel::NYTProf, and then decide.

Alternatively, say e.g.

 return {
 passed = ($r-success  !$r-has_unknown),
 map { $_ = scalar $r-$_ } qw(valid missing invalid unknown)
 };

(and you can get rid of the $passed variable earlier) to make this a simple 
transformation.

I forget when the use of variables as method names - for the $r-$_ bit - was 
introduced; it was probably perl 5.6.0, but it might be as late as 5.8.0. Either 
way, it should be safe for all but paleolithic environments.

Sam



I tried passing the $r object as:

return {  results = $r .};

.. before posting but calling -method produced the same problems at 
the other end. This may be more to do with basic Perl than DFV but I'm 
still not clear why assigning $r-method as a hash value doesn't invoke 
a scalar context, which is what I wanted rather than the array context 
option for $r-method. In the end I found:


$results{missing} = $r-missing if $r-has_missing;
return \%results;

 more useful anyway so problem solved.

gvim




Re: Assign method call to hash value?

2013-01-29 Thread pierre masci
  I'm still not clear why assigning $r-method as a hash value doesn't invoke 
 a scalar
 context, which is what I wanted rather than the array context option for
 $r-method. In the end I found:

 gvim

1. assigning $r-method does not invoke any context.
In this case, the context is we are inside a hash.

2. A hash is a list.
It's just a list which knows that its elements are coupled 2 by 2.
As a consequence, inside a hash you are in list context.

3. In this list context, any method that is context-sensitive will
return a list.
If you want to force your method to return a scalar anyway,
you have to use the scalar() function.

Is that clear?
If not, which part is not clear?


Re: Assign method call to hash value?

2013-01-29 Thread gvim

On 29/01/2013 12:44, pierre masci wrote:


1. assigning $r-method does not invoke any context.
In this case, the context is we are inside a hash.

2. A hash is a list.
It's just a list which knows that its elements are coupled 2 by 2.
As a consequence, inside a hash you are in list context.

3. In this list context, any method that is context-sensitive will
return a list.
If you want to force your method to return a scalar anyway,
you have to use the scalar() function.

Is that clear?
If not, which part is not clear?



Yes, clearer, thanks. My understanding was that, yes, a hash is a list 
but I mistakenly assumed it meant a list of scalars.


gvim


Re: Assign method call to hash value?

2013-01-29 Thread Dave Cross

Quoting gvim gvi...@gmail.com:


a hash is a list but I mistakenly assumed it meant a list of scalars.


That wasn't your mistake. A hash *is* (composed from) a list of  
scalars. There is no other kind of list in Perl.


You mistake was (apparently) assuming that a subroutine called as part  
of a hash initialisation would be called in scalar context. I hope  
we've now cleared that up.


Dave...


Re: Assign method call to hash value?

2013-01-29 Thread William Blunn

On 29/01/2013 11:36, gvim wrote:

On 29/01/2013 02:33, Mike Stok wrote:

Have you tried reading

   perldoc -f scalar

Hope this helps,

Mike



Yes, I'm aware of the scalar function but still not clear why 
assigning $r-method as a hash value doesn't invoke a scalar context 
in the first place.


The code

return { passed = $passed, valid = $r-valid, missing = $r-missing, invalid = 
$r-invalid, unknown = $r-unknown };

is equivalent to this

return { 'passed', $passed, 'valid', $r-valid, 'missing', $r-missing, 'invalid', 
$r-invalid, 'unknown', $r-unknown };

The bit inside the curly braces is not any kind of magical hash 
constructor but a list, plain and simple.


None of the values in that list know that they will eventually become 
a hash key or a hash value.


Everything in there is just in list context. So your method calls are in 
list context.


The curly braces then take the elements of that list, in pairs, and then 
treat each pair as (key, value) to build a hash.


(This links to a common discussion (linked in turn with the old 'return 
undef;' vs. 'return;' argument) about whether or not functions should 
behave differently depending on scalar and list context.)


Regards,

Bill


Re: Assign method call to hash value?

2013-01-29 Thread pierre masci
 The code

 return { passed = $passed, valid = $r-valid, missing = $r-missing,
 invalid = $r-invalid, unknown = $r-unknown };

 is equivalent to this

 return { 'passed', $passed, 'valid', $r-valid, 'missing', $r-missing,
 'invalid', $r-invalid, 'unknown', $r-unknown };

 The bit inside the curly braces is not any kind of magical hash
 constructor but a list, plain and simple.

And (tell me if i'm wrong) it's also equivalent to this:

my %result_hash = ( 'passed', $passed, 'valid', $r-valid, 'missing',
$r-missing, 'invalid', $r-invalid, 'unknown', $r-unknown );
return \%result_hash;

where the brackets clearly show that it's a list.


Re: Assign method call to hash value?

2013-01-29 Thread gvim

On 29/01/2013 14:09, pierre masci wrote:


And (tell me if i'm wrong) it's also equivalent to this:

my %result_hash = ( 'passed', $passed, 'valid', $r-valid, 'missing',
$r-missing, 'invalid', $r-invalid, 'unknown', $r-unknown );
return \%result_hash;

where the brackets clearly show that it's a list.



The hash = list is not where my confusion originated. It came more from 
the fact that the list is still a list of scalars so I couldn't 
understand why adding another element to the list did not invoke a 
scalar context, that's all. Anyway, Dave Cross cleared it up, thanks.


gvim


Re: Assign method call to hash value?

2013-01-29 Thread Daniel Perrett
=head1 TANGENT

... about the design of context in perl.

I get how you can do things like {%original, %changes}, but is there a
reason why the = couldn't add some magic and assume scalar context on
whatever it precedes? The only case I imagine it would break would be
a hypothetical {%original,  key= @odd_list }, but I don't know why
anyone would do that.

On 29 January 2013 14:18, gvim gvi...@gmail.com wrote:
 On 29/01/2013 14:09, pierre masci wrote:


 And (tell me if i'm wrong) it's also equivalent to this:

 my %result_hash = ( 'passed', $passed, 'valid', $r-valid, 'missing',
 $r-missing, 'invalid', $r-invalid, 'unknown', $r-unknown );
 return \%result_hash;

 where the brackets clearly show that it's a list.


 The hash = list is not where my confusion originated. It came more from the
 fact that the list is still a list of scalars so I couldn't understand why
 adding another element to the list did not invoke a scalar context, that's
 all. Anyway, Dave Cross cleared it up, thanks.

 gvim


Re: Assign method call to hash value?

2013-01-29 Thread Daniel Perrett
Apologies: so after consultation with #perl on IRC, my question has
been answered - Moose (for reasons I don't yet know) does stuff like

has 'foo' = ( is = 'rw' )

which would incorrectly be treated as

has 'foo' = 'rw'

So ignore my previous post.

Daniel

On 29 January 2013 21:12, Daniel Perrett perret...@googlemail.com wrote:
 =head1 TANGENT

 ... about the design of context in perl.

 I get how you can do things like {%original, %changes}, but is there a
 reason why the = couldn't add some magic and assume scalar context on
 whatever it precedes? The only case I imagine it would break would be
 a hypothetical {%original,  key= @odd_list }, but I don't know why
 anyone would do that.

 On 29 January 2013 14:18, gvim gvi...@gmail.com wrote:
 On 29/01/2013 14:09, pierre masci wrote:


 And (tell me if i'm wrong) it's also equivalent to this:

 my %result_hash = ( 'passed', $passed, 'valid', $r-valid, 'missing',
 $r-missing, 'invalid', $r-invalid, 'unknown', $r-unknown );
 return \%result_hash;

 where the brackets clearly show that it's a list.


 The hash = list is not where my confusion originated. It came more from the
 fact that the list is still a list of scalars so I couldn't understand why
 adding another element to the list did not invoke a scalar context, that's
 all. Anyway, Dave Cross cleared it up, thanks.

 gvim


Re: Assign method call to hash value?

2013-01-29 Thread Randal L. Schwartz
 Jasper == Jasper  jaspermcc...@gmail.com writes:

Jasper On 29 January 2013 11:36, gvim gvi...@gmail.com wrote:
 Yes, I'm aware of the scalar function but still not clear why assigning
 $r-method as a hash value doesn't invoke a scalar context in the first
 place.


Jasper Is there any context in the braces? It's just a (albeit fat) comma
Jasper separated list of stuff, isn't it?

In general, this is dangerous:

my $hashref = { foo = somefunc(), bar = otherfunc() };

You are invoking somefunc() and otherfunc() in *LIST* context.

They may or may not return a single scalar.  They more likely will
return a list, or empty.  And your hash will be messed up.

Better written as:

my $hashref = { foo = scalar somefunc(), bar = scalar otherfunc() };

Then you can be assured of a two-element hash.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
mer...@stonehenge.com URL:http://www.stonehenge.com/merlyn/
Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
See http://methodsandmessages.posterous.com/ for Smalltalk discussion


Re: Assign method call to hash value?

2013-01-28 Thread Mike Stok
Have you tried reading

  perldoc -f scalar

Hope this helps,

Mike

On 2013-01-28, at 8:45 PM, gvim gvi...@gmail.com wrote:

 I have a form validation sub thus:
 
 sub val {
  my $params = shift;
  my $r = Data::FormValidator-check($params, \%register);
  my $passed = $r-success  !$r-has_unknown;
  my $valid = $r-valid;
  my $missing = $r-missing;
  my $invalid = $r-invalid;
  my $unknown = $r-unknown;
  return { passed = $passed, valid = $valid, missing = $missing, invalid = 
 $invalid, unknown = $unknown };
 }
 
 It works but is it possible to call $r-method directly when assigning a hash 
 value, which is still a scalar context? I tried this:
 
  return { passed = $passed, valid = $r-valid, missing = $r-missing, 
 invalid = $r-invalid, unknown = $r-unknown };
 
 ... but didn't get the same result. Adding $r-method() didn't make any 
 difference, nor did curly-quoting: {$r-method()}.
 
 gvim

-- 

Mike Stok m...@stok.ca
http://www.stok.ca/~mike/

The `Stok' disclaimers apply.







Re: Assign method call to hash value?

2013-01-28 Thread Sam Kington
On 29 Jan 2013, at 01:45, gvim gvi...@gmail.com wrote:
I have a form validation sub thus:
 
 sub val {
  my $params = shift;
  my $r = Data::FormValidator-check($params, \%register);
  my $passed = $r-success  !$r-has_unknown;
  my $valid = $r-valid;
  my $missing = $r-missing;
  my $invalid = $r-invalid;
  my $unknown = $r-unknown;
  return { passed = $passed, valid = $valid, missing = $missing, invalid = 
 $invalid, unknown = $unknown };
 }
 
 It works but is it possible to call $r-method directly when assigning a hash 
 value, which is still a scalar context? I tried this:
 
  return { passed = $passed, valid = $r-valid, missing = $r-missing, 
 invalid = $r-invalid, unknown = $r-unknown };
 
 ... but didn't get the same result. Adding $r-method() didn't make any 
 difference, nor did curly-quoting: {$r-method()}.

As Mike mentioned, you almost certainly want to say { ... valid = scalar 
$r-valid, ... } instead; checking the documentation for Data::FormValidator 
and seeing what it says the missing, valid and unknown methods return in list 
context vs scalar context, might help.

https://metacpan.org/module/Data::FormValidator#check- says It returns its 
results as a Data::FormValidator::Results object and e.g. the documentation 
for the missing method says

 In an array context it returns the list of fields which are missing. In a 
 scalar context, it returns an array reference to the list of missing fields.
 
 If called with an argument, it returns true if that field is missing, undef 
 otherwise.

So you could replace the last 5 lines of your sub with e.g.

return {
passed  = $passed,
valid   = scalar $r-valid,
missing = scalar $r-missing,
invalid = scalar $r-invalid,
unknown = scalar $r-unknown,
};

Once written like that, it becomes clear that there's some repetition going on.

There's two things you could do at this point. Depending on what you need to do 
later on, you might just say

return { passed = $passed, form_validator_results = $r };

and let the calling code fish out the stuff it needs. This might be mildly more 
efficient if it ever turns out that calling the valid, missing, invalid and 
unknown methods ahead of time was wasteful if the calling code didn't need that 
information. Or it might not; benchmark your code, if performance is a problem, 
with Devel::NYTProf, and then decide.

Alternatively, say e.g.

return {
passed = ($r-success  !$r-has_unknown),
map { $_ = scalar $r-$_ } qw(valid missing invalid unknown)
};

(and you can get rid of the $passed variable earlier) to make this a simple 
transformation.

I forget when the use of variables as method names - for the $r-$_ bit - was 
introduced; it was probably perl 5.6.0, but it might be as late as 5.8.0. 
Either way, it should be safe for all but paleolithic environments.

Sam
-- 
Website: http://www.illuminated.co.uk/