Re: Assign method call to hash value?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
=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?
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?
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?
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?
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/