Re: What is the difference between the constant construct in Perl and the Readonly construct in Perl?
by revdiablo (Prior) on Jul 06, 2006 at 00:58 UTC
|
I think some of your basic assumptions might be incorrect. It does not appear that Readonly is a core module, and it appears that you have the syntax for its usage wrong. From what I'm seeing, Readonly allows you to set a normal, sigil-bearing variable to read only, and use it in the standard manner. By comparison, constant gives you a bareword constant that you can't use in all the same contexts as a normal variable (e.g. stringwise evaluation of scalars). So it my mind, it boils down to the following tradeoff:
Is the cost of installing the CPAN module outweighed by the utility of being able to use the value more conveniently?
And that's really something you need to answer for yourself.
Update: for future reference, you can see what modules are included in the standard perl distribution by reading perlmodlib. And you can also find what version a certain module became core with the help of Module::CoreList.
| [reply] [d/l] |
Re: What is the difference between the constant construct in Perl and the Readonly construct in Perl?
by diotalevi (Canon) on Jul 06, 2006 at 01:26 UTC
|
The author of Readonly has inspired my ire by neglecting to mention the positive reasons to use constant. I wrote a note at AnnoCPAN and I'm reproducing it for you here as well. You didn't mention that the constant pragma allows the value to get inlined into the optree. You also didn't mention that when constants are used in conditionals, perl is able to optimize away the non-executable branches. Further you didn't mention that constant.pm tracks perl's preferred implementation for constants. Prior to 5.9.4 constants were implemented as functions like sub FOO () { 1 }. After that perl does something a little bit different which allows for a smaller memory footprint.
| [reply] |
|
I agree. that was one of the few things I didn't like while reading PBP.
To many people speed doesn't seem to be important. But if I hadn't used
constant in my HTC module, it would
probably be much slower than it is (I use a lot of constants there...)
and I think at least in modules speed is a bit more important than in
application code.
| [reply] [d/l] |
|
| [reply] |
|
well, i think speed is always an issue!
| [reply] |
|
While you're often right with this, and certainly in this case too (++), be careful not to generalise:
In many other places, speed may not be so much of an issue =)
Cheers, Sören
| [reply] |
|
Re: What is the difference between the constant construct in Perl and the Readonly construct in Perl?
by davido (Cardinal) on Jul 06, 2006 at 01:27 UTC
|
use Readonly PI => 3.141593;
will generate the following error message:
Readonly version 3.14 required--this is only version 1.03 at C:/Perl/l
+ib/Exporter/Heavy.pm line 121.
BEGIN failed--compilation aborted at mytest.pl line 5.
You probably mean to say the following:
use Readonly;
Readonly my $PI => 3.141592654;
print "$PI\n";
In which case, it should be immediately apparent what the differences between use constant and Readonly are. For one thing, the Readonly function creates a readonly scalar, hash, or array. These entities can be lexically scoped or they can be package globals. And they retain most of the characteristics of an ordinary Perl variable. They have a sigil ($, %, or @), and interpolation rules follow those of any ordinary Perl variable. These enhancements over the tired use constant pragma are significant, and solve issues that diminished the usefulness of the constant pragma.
If you were to try to modify that readonly variable, as in $PI = 3.5;, Readonly will die with an error message like this: Modification of a read-only value attempted at test.pl line 13.
There are a few other pros to using Readonly, and a Con also (having to do with speed), which can be improved upon by also installing Readonly::XS. Have a look at the documentation for Readonly, and I think you'll see. It provides a great list of pros and cons, and also describes the implications of installing the XS companion module. I was turned on to the module by reading Perl Best Practices.
| [reply] [d/l] [select] |
|
| [reply] |
Re: What is the difference between the constant construct in Perl and the Readonly construct in Perl?
by jdtoronto (Prior) on Jul 06, 2006 at 01:19 UTC
|
As revdiablo has said Readonly is not a core module, whereas constant is a pragma. There are some shortcomings in the use of the constant pragma and all of those are in fact well pointed out in the documentation for Readonly. However Readonly has a performance penalty and there is at least one 'speed up' module ( Readonly::xs ) on CPAN for it and some useful alternatives. One particularly cunning one is Scalar::Readonly which although it works only on scalars allows you to programatically 'write enable' a variable, update it and then lock it again. Of course the variable can be tested as well.
I will very rarely use constant, I have never used Readonly. We do some tricks using Scalar::Readonly ocasionally.
jdtoronto | [reply] |
Re: What is the difference between the constant construct in Perl and the Readonly construct in Perl?
by BrowserUk (Patriarch) on Jul 06, 2006 at 02:07 UTC
|
Besides all the optimisation features of constant so carefully omitted by the Readonly docs (as noted by diotalevi++), another of things I especially like about
use constant SYMBOL => 123;,
is that my constants don't look like variables.
All the hyperbole about Readonly exported variables being immutable makes me think of nothing more than the old saying about constants that aren't and variables that won't. I cannot imagine why anyone would want their constants to look like variables?
The minor inconvenience of using (s)printf in order to embed the values of constants into strings is actually a plus. If I define pi in my program, I'm gonna define it to the full accuracy of whatever math I'm using supports. For standard floats that's use constant PI => 3.1415926535897931; in order to use the best accuracy in my calculations. But if I'm going to display pi, I'm probably going to settle for showing 3 or 4 decimal places. (s)printf are the tool for this, so it works out great.
Another ill-thought through solution to a non-problem foisted on the world under the title of a best practice.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
|
For standard floats that's use constant PI => 3.1415926535897931;
I can't help but comment, even if it's OT, obscure, and makes absolutely no practical difference. It's still, ever so slightly, wrong
It should be PI => 3.1415926535897932;
There, I feel better.
By the way, I thought your closing, "Another ill-thought through solution to a non-problem foisted on the world under the title of a best practice." was a nice expression of opinion, both precise and articulate (though not at all one with which I agree.) However, if one doesn't read it carefully, it can remind those in the US of a typical american rant, and there's now doubt those who took it that way. (Over here, we're little familliar with the articulate verbal sparring of Gladsone and Disraeli, or their decendants.) I'm just offering clarification; I'm not suggesting you do anything differently.
| [reply] |
|
PI => 3.1415926535897932;
Ah but...
printf "%19.17f\n", 3.1415926535897932;;
3.14159265358979310
Blame IEEE 754, not me :)
... articulate verbal sparring of Gladsone and Disraeli ...
I wish. Baldrick maybe ;)
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
|
I cannot imagine why anyone would want their constants to look like variables?
Because variables Do What We Want without constant bletcherosity like the $foo{+BAR} hack? Which is buried way down in the bugs section of perldoc constant where nobody is going to see it, by the way. Seriously, someone ought to collect up all the "How do I do X with a constant?" FAQs and answer them right up at the top of the documentation.
| [reply] |
A reply falls below the community's threshold of quality. You may see it by logging in. |
Re: What is the difference between the constant construct in Perl and the Readonly construct in Perl?
by xdg (Monsignor) on Jul 06, 2006 at 01:20 UTC
|
Also, according to Re^3: Import constants as scalar instead of bareword sub, Readonly uses tie (even in XS mode), which will have a speed hit.
-xdg
Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.
| [reply] [d/l] [select] |
Re: What is the difference between the constant construct in Perl and the Readonly construct in Perl?
by tfrayner (Curate) on Jul 06, 2006 at 09:36 UTC
|
Hi,
A key feature (in my view) of Readonly that others haven't mentioned yet is that a Readonly hashref will prevent you from modifying the referenced hash. The constant pragma, in contrast, only prevents you from changing the top-level reference value. The constant will always point to the same hash, but that hash can be modified. Maybe this might change in future, I don't know, but in the meantime I've been bitten by this not-entirely-constant nature of the constant pragma (inadvertently using a "constant" hash as a global variable...). It's fine for scalar and array values, but a bit dodgy for hashes, IMHO.
cheers, Tim | [reply] |
Re: What is the difference between the constant construct in Perl and the Readonly construct in Perl?
by duff (Parson) on Jul 06, 2006 at 02:53 UTC
|
If some more of perl6 makes it into perl5 we might have a third option before long--a constant declarator. Here's what it will look like in perl6:
constant $PI = 3.141593;
See the section of Synopsis 3 on declarators for more info.
This should be easy to hack into perl5 for scalars, but I'm not sure about arrays and such.
| [reply] [d/l] [select] |
Re: What is the difference between the constant construct in Perl and the Readonly construct in Perl?
by Moron (Curate) on Jul 06, 2006 at 13:59 UTC
|
A constant causes lexical substitution to take place for instances of the bareword found within the scope of the constant declaration.
Readonly controls access to variables not barewords. The conditions for Readonly instead of using a constant bareword tend to be where the "constant" value is unknown prior to entry into the relevant scope, whereas a constant is known in advance of execution and tends to be used to minimise hardcoding.
# example of constant:
# use constant TMPDIR = '/bigdrive/bigbucket01';
use constant TMPDIR = '/tmp'; # /tmp now mapped to above
# example of Readonly:
sub Write {
my $self = shift;
Readonly my %reset = %$self;
# ... code that modifies $self
# e.g. with 'dangerous' use of eval ...
$self -> ( STATE } = eval $self -> { COMMAND }
or goto ERROR;
# ...
$self -> Close() and return 1;
# if error reset $self:
ERROR:
delete $self -> { $_} for keys %$self;
$self -> { $_ } = $reset{ $_ } for keys %reset;
return 0;
}
| [reply] [d/l] |
Re: What is the difference between the constant construct in Perl and the Readonly construct in Perl?
by demerphq (Chancellor) on Jul 07, 2006 at 13:23 UTC
|
Personally I think that I wouldnt use the Readonly module. Partially because what it does is done elsewhere, and i'd be more likely to look there, (Hash::Util for instance would be where i would look for locked hashes). But also because the semantics of readonlyness IMO isnt all that clear. For instance should the readonlyness transfer on assignment? (It doesn't).
The other thing that makes me wonder, is why does the module go to such extreme lengths? Making a constant scalar (which seems to me to be a common task mentioned in this list) is pretty easy without it:
our $constant;
*constant=\"this string is a constant";
Which might not be self documenting, but it solves 99% of the problem domain in a way that doesnt require modules and should work everywhere.
---
$world=~s/war/peace/g
| [reply] [d/l] |
Re: What is the difference between the constant construct in Perl and the Readonly construct in Perl?
by PerlingTheUK (Hermit) on Jul 07, 2006 at 11:36 UTC
|
Other than just the above mentioned it also allows you to assign an array or hash directly as Readonly.
Readonly my @vals => (1,2,3,4);
Readonly my %vals => (1=>2);
If I am not mistaken constant is also assigned at compile time. So using Readonly inside a function to take the parameters would work, the same would not work for constant.
| [reply] [d/l] |