[libreadonly-perl] 01/06: Imported Upstream version 1.500.0
gregor herrmann
gregoa at debian.org
Thu Jun 26 18:56:20 UTC 2014
This is an automated email from the git hooks/post-receive script.
gregoa pushed a commit to branch master
in repository libreadonly-perl.
commit d74cfd0e38302b8dc5f7d2d18e41e0130291e5a6
Author: gregor herrmann <gregoa at debian.org>
Date: Thu Jun 26 20:35:06 2014 +0200
Imported Upstream version 1.500.0
---
Build.PL | 2 +-
Changes | 101 +++++----
MANIFEST | 33 +--
MANIFEST.SKIP | 59 ------
META.json | 29 +--
META.yml | 35 ++--
README.md | 257 ++++++++++++-----------
cpanfile | 3 +-
eg/benchmark.pl | 78 ++++---
lib/Readonly.pm | 451 ++++++++++++++++++++++++++---------------
lib/Readonly/Array.pm | 34 ----
lib/Readonly/Hash.pm | 38 ----
lib/Readonly/Scalar.pm | 21 --
t/{ => general}/docs.t | 2 +-
t/{ => general}/export.t | 2 +-
t/{ => general}/tie.t | 2 +-
t/{ => simple_api}/array.t | 10 +-
t/{ => simple_api}/hash.t | 8 +-
t/{ => simple_api}/readonly.t | 20 +-
t/{ => simple_api}/reassign.t | 34 ++--
t/{ => simple_api}/scalar.t | 23 +--
t/{ => verbose_api}/array.t | 2 +-
t/{ => verbose_api}/deepa.t | 1 -
t/{ => verbose_api}/deeph.t | 2 +-
t/{ => verbose_api}/deeps.t | 4 +-
t/{ => verbose_api}/hash.t | 2 +-
t/{ => verbose_api}/readonly.t | 20 +-
t/{ => verbose_api}/reassign.t | 8 +-
t/{ => verbose_api}/scalar.t | 2 +-
29 files changed, 655 insertions(+), 628 deletions(-)
diff --git a/Build.PL b/Build.PL
index 91ccf14..9156557 100644
--- a/Build.PL
+++ b/Build.PL
@@ -34,7 +34,7 @@ my %args = (
test_files => ((-d '.git' || $ENV{RELEASE_TESTING}) && -d 'xt') ? 't/ xt/' : 't/',
recursive_test_files => 1,
-
+
);
if (-d 'share') {
$args{share_dir} = 'share';
diff --git a/Changes b/Changes
index 620af43..e257736 100644
--- a/Changes
+++ b/Changes
@@ -1,48 +1,63 @@
Revision history for Perl extension Readonly.
+v1.500.0 2014-06-25T19:56:18Z
+ - PLEASE NOTE: Readonly::XS is no longer needed!
+ - Again, Readonly::XS is no longer needed.
+ - Merged typo fix from David Steinbrunner RT#86350/#2
+ - Merged patch (w/ tests, yay!) from Daniel P. Risse RT#37864
+ - Upstream magic related bugs were reported to p5p and fixed in perl
+ itself so we can resolve the following local issues: RT#70167, RT#57382,
+ RT#29487, RT#36653, RT#24216.
+ - Reported RT#120122 (tie + smartmatch bug) upstream to p5p. Will
+ eventually resolve local [RT#59256].
+ - Note: Resolved RT#16167 (benchmark.pl being installed) in 1.04.
+ - Use readonly support exposed in Internals on perl >=5.8.x
+ - Have I mentioned you don't need to install Readonly::XS anymore?
+ - Checking $Readonly::XSokay is no longer suggested. ...never should have been
+
1.04 2013-11-26T01:20:38Z
- - Module now maintained by Sanko Robinson. Please see TODO for a possible
- set of changes to this module that may effect code written for old, pre-
- perl 5.14.0 platforms!!!
+ - Module now maintained by Sanko Robinson. Please see TODO for a possible
+ set of changes to this module that may effect code written for old, pre-
+ perl 5.14.0 platforms!!!
1.03 2004 April 20
- - Changed the prototype for Readonly, to make the usage cleaner.
- Unfortunately, this breaks backwards-compatability for this
- function. Users of this function who have Perl 5.8 or later
- will have to change their source code. Also, users of this
- function who upgrade to perl 5.8+ will have to change their
- usage. Having discussed this feature change with a number of
- people, I felt that breaking compatability was worth the gain
- in simplicity of usage.
- (Thanks to Damian Conway for the suggestion).
- - Removed "use warnings" so the module will work in perl 5.005.
+ - Changed the prototype for Readonly, to make the usage cleaner.
+ Unfortunately, this breaks backwards-compatability for this
+ function. Users of this function who have Perl 5.8 or later
+ will have to change their source code. Also, users of this
+ function who upgrade to perl 5.8+ will have to change their
+ usage. Having discussed this feature change with a number of
+ people, I felt that breaking compatability was worth the gain
+ in simplicity of usage.
+ (Thanks to Damian Conway for the suggestion).
+ - Removed "use warnings" so the module will work in perl 5.005.
1.02 2003 May 13
- - If Readonly::XS is installed, Readonly will use it for
- making scalars read-only.
- - Callers are now forbidden to tie variables directly. This
- prevents sneaky callers from reassigning a variable via
- tie.
- - Error messages have been changed to be more like Perl's
- own "Modification of a read-only value attempted at..."
- - Catch and return an error if user tries to pass a constant
- to Readonly::Scalar (eg Readonly::Scalar 'hello', 'goodbye')
- - Include a simple benchmark script.
- - Add a few more test cases. You can never have too many.
- - Add a simple benchmark program.
+ - If Readonly::XS is installed, Readonly will use it for
+ making scalars read-only.
+ - Callers are now forbidden to tie variables directly. This
+ prevents sneaky callers from reassigning a variable via
+ tie.
+ - Error messages have been changed to be more like Perl's
+ own "Modification of a read-only value attempted at..."
+ - Catch and return an error if user tries to pass a constant
+ to Readonly::Scalar (eg Readonly::Scalar 'hello', 'goodbye')
+ - Include a simple benchmark script.
+ - Add a few more test cases. You can never have too many.
+ - Add a simple benchmark program.
1.01 2003 February 14
- - Add some checking to prevent reassignment of Readonly variables.
- - Changed my email address in the docs.
+ - Add some checking to prevent reassignment of Readonly variables.
+ - Changed my email address in the docs.
1.00 2003 January 7
- - No code changes. No bugs or suggestions have been reported
- for six months, so the version number is changing to 1.00.
+ - No code changes. No bugs or suggestions have been reported
+ for six months, so the version number is changing to 1.00.
0.07 2002 June 25
- - Clean up the code somewhat; remove redundancies; delay
- loading Carp.pm until it's needed.
- - Fixed the list of EXPORT_OK symbols.
+ - Clean up the code somewhat; remove redundancies; delay
+ loading Carp.pm until it's needed.
+ - Fixed the list of EXPORT_OK symbols.
0.06 2002 June 16
- Add Readonly function, to provide a unified (and shorter) way to
@@ -53,22 +68,22 @@ Revision history for Perl extension Readonly.
- Switch to Test::More and Test::Harness. 134 tests now!
0.05 2002 March 15
- - Change name from Constant.pm to Readonly.pm, due to file
- naming conflict under Windows.
- - Changed docs to match.
- - Allow Readonly::Hash to accept a hash reference parameter.
- - Works better with older versions of Perl.
- - Add many, many test cases to test.pl.
+ - Change name from Constant.pm to Readonly.pm, due to file
+ naming conflict under Windows.
+ - Changed docs to match.
+ - Allow Readonly::Hash to accept a hash reference parameter.
+ - Works better with older versions of Perl.
+ - Add many, many test cases to test.pl.
0.04 2002 March 7
- - Add top-level Scalar, Array, and Hash functions, so callers
- don't have to tie the variables themselves.
+ - Add top-level Scalar, Array, and Hash functions, so callers
+ don't have to tie the variables themselves.
0.03 2001 September 9
- - documentation changes only.
+ - documentation changes only.
0.02 2001 September 9
- - documentation changes only.
+ - documentation changes only.
0.01 2001 August 30
- - Constant.pm, original version.
+ - Constant.pm, original version.
diff --git a/MANIFEST b/MANIFEST
index ae09c72..7e71139 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,26 +1,27 @@
-Build.PL
Changes
LICENSE
-MANIFEST.SKIP
README.md
TODO
cpanfile
eg/benchmark.pl
lib/Readonly.pm
-lib/Readonly/Array.pm
-lib/Readonly/Hash.pm
-lib/Readonly/Scalar.pm
-t/array.t
-t/deepa.t
-t/deeph.t
-t/deeps.t
-t/docs.t
-t/export.t
-t/hash.t
-t/readonly.t
-t/reassign.t
-t/scalar.t
-t/tie.t
+t/general/docs.t
+t/general/export.t
+t/general/tie.t
+t/simple_api/array.t
+t/simple_api/hash.t
+t/simple_api/readonly.t
+t/simple_api/reassign.t
+t/simple_api/scalar.t
+t/verbose_api/array.t
+t/verbose_api/deepa.t
+t/verbose_api/deeph.t
+t/verbose_api/deeps.t
+t/verbose_api/hash.t
+t/verbose_api/readonly.t
+t/verbose_api/reassign.t
+t/verbose_api/scalar.t
+Build.PL
META.json
META.yml
MANIFEST
\ No newline at end of file
diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP
deleted file mode 100644
index 1a95c21..0000000
--- a/MANIFEST.SKIP
+++ /dev/null
@@ -1,59 +0,0 @@
-
-#!start included C:\strawberry\perl\lib\ExtUtils\MANIFEST.SKIP
-# Avoid version control files.
-\bRCS\b
-\bCVS\b
-\bSCCS\b
-,v$
-\B\.svn\b
-\B\.git\b
-\B\.gitignore\b
-\b_darcs\b
-\B\.cvsignore$
-
-# Avoid VMS specific MakeMaker generated files
-\bDescrip.MMS$
-\bDESCRIP.MMS$
-\bdescrip.mms$
-
-# Avoid Makemaker generated and utility files.
-\bMANIFEST\.bak
-\bMakefile$
-\bblib/
-\bMakeMaker-\d
-\bpm_to_blib\.ts$
-\bpm_to_blib$
-\bblibdirs\.ts$ # 6.18 through 6.25 generated this
-
-# Avoid Module::Build generated and utility files.
-\bBuild$
-\b_build/
-\bBuild.bat$
-\bBuild.COM$
-\bBUILD.COM$
-\bbuild.com$
-
-# Avoid temp and backup files.
-~$
-\.old$
-\#$
-\b\.#
-\.bak$
-\.tmp$
-\.#
-\.rej$
-
-# Avoid OS-specific files/dirs
-# Mac OSX metadata
-\B\.DS_Store
-# Mac OSX SMB mount metadata files
-\B\._
-
-# Avoid Devel::Cover and Devel::CoverX::Covered files.
-\bcover_db\b
-\bcovered\b
-
-# Avoid MYMETA files
-^MYMETA\.
-#!end included C:\strawberry\perl\lib\ExtUtils\MANIFEST.SKIP
-
diff --git a/META.json b/META.json
index 8b0d582..c4f8c3d 100644
--- a/META.json
+++ b/META.json
@@ -4,7 +4,7 @@
"Sanko Robinson <sanko at cpan.org> - http://sankorobinson.com/"
],
"dynamic_config" : 0,
- "generated_by" : "Minilla/v0.10.0",
+ "generated_by" : "Minilla/v1.1.0",
"license" : [
"perl_5"
],
@@ -36,18 +36,18 @@
"develop" : {
"requires" : {
"Test::CPAN::Meta" : "0",
- "Test::MinimumVersion" : "0.10108",
+ "Test::MinimumVersion::Fast" : "0.04",
+ "Test::PAUSE::Permissions" : "0.04",
"Test::Pod" : "1.41",
"Test::Spellunker" : "v0.2.7"
}
},
"runtime" : {
"recommends" : {
- "Readonly::XS" : "1.06",
- "perl" : "v5.10.0"
+ "perl" : "v5.20.0"
},
"requires" : {
- "perl" : "5.006"
+ "perl" : "v5.6.0"
}
},
"test" : {
@@ -59,19 +59,19 @@
"provides" : {
"Readonly" : {
"file" : "lib/Readonly.pm",
- "version" : "1.04"
+ "version" : "v1.500.0"
},
"Readonly::Array" : {
- "file" : "lib/Readonly/Array.pm",
- "version" : "1.04"
+ "file" : "lib/Readonly.pm",
+ "version" : "1.05"
},
"Readonly::Hash" : {
- "file" : "lib/Readonly/Hash.pm",
- "version" : "1.04"
+ "file" : "lib/Readonly.pm",
+ "version" : "1.05"
},
"Readonly::Scalar" : {
- "file" : "lib/Readonly/Scalar.pm",
- "version" : "1.04"
+ "file" : "lib/Readonly.pm",
+ "version" : "1.05"
}
},
"release_status" : "stable",
@@ -85,5 +85,8 @@
"web" : "https://github.com/sanko/readonly"
}
},
- "version" : "1.04"
+ "version" : "v1.500.0",
+ "x_contributors" : [
+ "David Steinbrunner <dsteinbrunner at pobox.com>"
+ ]
}
diff --git a/META.yml b/META.yml
index 49fabe4..a1b1209 100644
--- a/META.yml
+++ b/META.yml
@@ -3,17 +3,17 @@ abstract: 'Facility for creating read-only scalars, arrays, hashes'
author:
- 'Sanko Robinson <sanko at cpan.org> - http://sankorobinson.com/'
build_requires:
- Test::More: 0
+ Test::More: '0'
configure_requires:
- CPAN::Meta: 0
- CPAN::Meta::Prereqs: 0
- Module::Build: 0.38
+ CPAN::Meta: '0'
+ CPAN::Meta::Prereqs: '0'
+ Module::Build: '0.38'
dynamic_config: 0
-generated_by: 'Minilla/v0.10.0, CPAN::Meta::Converter version 2.132140'
+generated_by: 'Minilla/v1.1.0, CPAN::Meta::Converter version 2.141170'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
- version: 1.4
+ version: '1.4'
name: Readonly
no_index:
directory:
@@ -28,23 +28,24 @@ no_index:
provides:
Readonly:
file: lib/Readonly.pm
- version: 1.04
+ version: v1.500.0
Readonly::Array:
- file: lib/Readonly/Array.pm
- version: 1.04
+ file: lib/Readonly.pm
+ version: '1.05'
Readonly::Hash:
- file: lib/Readonly/Hash.pm
- version: 1.04
+ file: lib/Readonly.pm
+ version: '1.05'
Readonly::Scalar:
- file: lib/Readonly/Scalar.pm
- version: 1.04
+ file: lib/Readonly.pm
+ version: '1.05'
recommends:
- Readonly::XS: 1.06
- perl: v5.10.0
+ perl: v5.20.0
requires:
- perl: 5.006
+ perl: v5.6.0
resources:
bugtracker: https://github.com/sanko/readonly/issues
homepage: https://github.com/sanko/readonly
repository: https://github.com/sanko/readonly.git
-version: 1.04
+version: v1.500.0
+x_contributors:
+ - 'David Steinbrunner <dsteinbrunner at pobox.com>'
diff --git a/README.md b/README.md
index 6037d4e..8490ae0 100644
--- a/README.md
+++ b/README.md
@@ -6,15 +6,15 @@ Readonly - Facility for creating read-only scalars, arrays, hashes
use Readonly;
- # Read-only scalar
+ # Deep Read-only scalar
Readonly::Scalar $sca => $initial_value;
Readonly::Scalar my $sca => $initial_value;
- # Read-only array
+ # Deep Read-only array
Readonly::Array @arr => @values;
Readonly::Array my @arr => @values;
- # Read-only hash
+ # Deep Read-only hash
Readonly::Hash %has => (key => value, key => value, ...);
Readonly::Hash my %has => (key => value, key => value, ...);
# or:
@@ -49,23 +49,33 @@ Readonly - Facility for creating read-only scalars, arrays, hashes
# Description
-This is a facility for creating non-modifiable variables. This is useful for
-configuration files, headers, etc. It can also be useful as a development and
-debugging tool, for catching updates to variables that should not be changed.
+This is a facility for creating non-modifiable variables. This is useful for
+configuration files, headers, etc. It can also be useful as a development and
+debugging tool for catching updates to variables that should not be changed.
-If any of the values you pass to `Scalar`, `Array`, or `Hash` are
-references, then those functions recurse over the data structures, marking
-everything as Readonly. Usually, this is what you want: the entire structure
-nonmodifiable. If you want only the top level to be Readonly, use the
-alternate `Scalar1`, `Array1` and `Hash1` functions.
+# Variable Depth
-Please note that most users of Readonly will also want to install a companion
-module Readonly::XS. See the ["Cons"](#cons) section below for more details.
+Readonly has the ability to create both deep and shallow readonly variables.
-# Comparison with "use constant"
+If any of the values you pass to `Scalar`, `Array`, `Hash`, or the standard
+`Readonly` are references, then those functions recurse over the data
+structures, marking everything as Readonly. The entire structure is
+nonmodifiable. This is normally what you want.
+
+If you want only the top level to be Readonly, use the alternate (and poorly
+named) `Scalar1`, `Array1`, and `Hash1` functions.
+
+#
+
+# The Past
+
+The following sections are updated versions of the previous authors
+documentation.
+
+## Comparison with "use constant"
Perl provides a facility for creating constant values, via the [constant](https://metacpan.org/pod/constant)
-pragma. There are several problems with this pragma.
+pragma. There are several problems with this pragma.
- The constants created have no leading sigils.
- These constants cannot be interpolated into strings.
@@ -74,6 +84,7 @@ pragma. There are several problems with this pragma.
use constant CARRAY => (2, 3, 5, 7, 11, 13);
$a_prime = CARRAY[2]; # wrong!
$a_prime = (CARRAY)[2]; # right -- MUST use parentheses
+
- You have to be very careful in places where barewords are allowed.
For example:
@@ -83,10 +94,10 @@ pragma. There are several problems with this pragma.
$some_value = $hash{SOME_KEY}; # wrong!
$some_value = $hash{+SOME_KEY}; # right
- (who thinks to use a unary plus when using a hash?)
+ (who thinks to use a unary plus when using a hash to scalarize the key?)
- `use constant` works for scalars and arrays, not hashes.
-- These constants are global ot the package in which they're declared;
+- These constants are global to the package in which they're declared;
cannot be lexically scoped.
- Works only at compile time.
- Can be overridden:
@@ -102,143 +113,116 @@ structures) with `use constant`.
# Comparison with typeglob constants
-Another popular way to create read-only scalars is to modify the symbol
-table entry for the variable by using a typeglob:
+Another popular way to create read-only scalars is to modify the symbol table
+entry for the variable by using a typeglob:
*a = \'value';
-This works fine, but it only works for global variables ("my"
-variables have no symbol table entry). Also, the following similar
-constructs do __not__ work:
+This works fine, but it only works for global variables ("my" variables have
+no symbol table entry). Also, the following similar constructs do **not** work:
*a = [1, 2, 3]; # Does NOT create a read-only array
*a = { a => 'A'}; # Does NOT create a read-only hash
-# Pros
+## Pros
-Readonly.pm, on the other hand, will work with global variables and
-with lexical ("my") variables. It will create scalars, arrays, or
-hashes, all of which look and work like normal, read-write Perl
-variables. You can use them in scalar context, in list context; you
-can take references to them, pass them to functions, anything.
+Readonly.pm, on the other hand, will work with global variables and with
+lexical ("my") variables. It will create scalars, arrays, or hashes, all of
+which look and work like normal, read-write Perl variables. You can use them
+in scalar context, in list context; you can take references to them, pass them
+to functions, anything.
-Readonly.pm also works well with complex data structures, allowing you
-to tag the whole structure as nonmodifiable, or just the top level.
+Readonly.pm also works well with complex data structures, allowing you to tag
+the whole structure as nonmodifiable, or just the top level.
-Also, Readonly variables may not be reassigned. The following code will die:
+Also, Readonly variables may not be reassigned. The following code will die:
Readonly::Scalar $pi => 3.14159;
...
Readonly::Scalar $pi => 2.71828;
-# Cons
-
-Readonly.pm does impose a performance penalty. It's pretty slow. How
-slow? Run the `eg/benchmark.pl` script that comes with Readonly. On my
-test system, "use constant", typeglob constants, and regular
-read/write Perl variables were all about the same speed, and
-Readonly.pm constants were about 1/20 the speed.
-
-However, there is relief. There is a companion module available,
-Readonly::XS. If it is installed on your system, Readonly.pm uses it
-to make read-only scalars much faster. With Readonly::XS, Readonly
-scalars are as fast as the other types of variables. Readonly arrays
-and hashes will still be relatively slow. But it's likely that most
-of your Readonly variables will be scalars.
-
-If you can't use Readonly::XS (for example, if you don't have a C
-compiler, or your perl is statically linked and you don't want to
-re-link it), you have to decide whether the benefits of Readonly
-variables outweigh the speed issue. For most configuration variables
-(and other things that Readonly is likely to be useful for), the speed
-issue is probably not really a big problem. But benchmark your
-program if it might be. If it turns out to be a problem, you may
-still want to use Readonly.pm during development, to catch changes to
-variables that should not be changed, and then remove it for
-production:
-
- # For testing:
- Readonly::Scalar $Foo_Directory => '/usr/local/foo';
- Readonly::Scalar $Bar_Directory => '/usr/local/bar';
- # $Foo_Directory = '/usr/local/foo';
- # $Bar_Directory = '/usr/local/bar';
-
- # For production:
- # Readonly::Scalar $Foo_Directory => '/usr/local/foo';
- # Readonly::Scalar $Bar_Directory => '/usr/local/bar';
- $Foo_Directory = '/usr/local/foo';
- $Bar_Directory = '/usr/local/bar';
+## Cons
+
+Readonly.pm used to impose a performance penalty. It was pretty slow. How
+slow? Run the `eg/benchmark.pl` script that comes with Readonly. On my test
+system, "use constant" (const), typeglob constants (tglob), regular read/write
+Perl variables (normal/literal), and the new Readonly (ro/ro\_simple) are all
+about the same speed, the old, tie based Readonly.pm constants were about 1/22
+the speed.
+
+However, there is relief. There is a companion module available, Readonly::XS.
+You won't need this if you're using Perl 5.8.x or higher.
+
+I repeat, you do not need Readonly::XS if your environment has perl 5.8.x or
+higher. Please see section entitled [Internals](#internals) for more.
# Functions
- Readonly::Scalar $var => $value;
- Creates a nonmodifiable scalar, `$var`, and assigns a value of
- `$value` to it. Thereafter, its value may not be changed. Any
- attempt to modify the value will cause your program to die.
+ Creates a nonmodifiable scalar, `$var`, and assigns a value of `$value` to
+ it. Thereafter, its value may not be changed. Any attempt to modify the value
+ will cause your program to die.
- A value _must_ be supplied. If you want the variable to have
- `undef` as its value, you must specify `undef`.
+ A value _must_ be supplied. If you want the variable to have `undef` as its
+ value, you must specify `undef`.
- If `$value` is a reference to a scalar, array, or hash, then this
- function will mark the scalar, array, or hash it points to as being
- Readonly as well, and it will recursively traverse the structure,
- marking the whole thing as Readonly. Usually, this is what you want.
- However, if you want only the `$value` marked as Readonly, use
- `Scalar1`.
+ If `$value` is a reference to a scalar, array, or hash, then this function
+ will mark the scalar, array, or hash it points to as being Readonly as well,
+ and it will recursively traverse the structure, marking the whole thing as
+ Readonly. Usually, this is what you want. However, if you want only the
+ `$value` marked as Readonly, use `Scalar1`.
- If $var is already a Readonly variable, the program will die with
- an error about reassigning Readonly variables.
+ If $var is already a Readonly variable, the program will die with an error
+ about reassigning Readonly variables.
- Readonly::Array @arr => (value, value, ...);
- Creates a nonmodifiable array, `@arr`, and assigns the specified list
- of values to it. Thereafter, none of its values may be changed; the
- array may not be lengthened or shortened or spliced. Any attempt to
- do so will cause your program to die.
+ Creates a nonmodifiable array, `@arr`, and assigns the specified list of
+ values to it. Thereafter, none of its values may be changed; the array may not
+ be lengthened or shortened or spliced. Any attempt to do so will cause your
+ program to die.
- If any of the values passed is a reference to a scalar, array, or hash,
- then this function will mark the scalar, array, or hash it points to as
- being Readonly as well, and it will recursively traverse the structure,
- marking the whole thing as Readonly. Usually, this is what you want.
- However, if you want only the hash `%@arr` itself marked as Readonly,
- use `Array1`.
+ If any of the values passed is a reference to a scalar, array, or hash, then
+ this function will mark the scalar, array, or hash it points to as being
+ Readonly as well, and it will recursively traverse the structure, marking the
+ whole thing as Readonly. Usually, this is what you want. However, if you want
+ only the hash `%@arr` itself marked as Readonly, use `Array1`.
- If @arr is already a Readonly variable, the program will die with
- an error about reassigning Readonly variables.
+ If `@arr` is already a Readonly variable, the program will die with an error
+ about reassigning Readonly variables.
- Readonly::Hash %h => (key => value, key => value, ...);
- Readonly::Hash %h => {key => value, key => value, ...};
- Creates a nonmodifiable hash, `%h`, and assigns the specified keys
- and values to it. Thereafter, its keys or values may not be changed.
- Any attempt to do so will cause your program to die.
+ Creates a nonmodifiable hash, `%h`, and assigns the specified keys and values
+ to it. Thereafter, its keys or values may not be changed. Any attempt to do so
+ will cause your program to die.
- A list of keys and values may be specified (with parentheses in the
- synopsis above), or a hash reference may be specified (curly braces in
- the synopsis above). If a list is specified, it must have an even
- number of elements, or the function will die.
+ A list of keys and values may be specified (with parentheses in the synopsis
+ above), or a hash reference may be specified (curly braces in the synopsis
+ above). If a list is specified, it must have an even number of elements, or
+ the function will die.
- If any of the values is a reference to a scalar, array, or hash, then
- this function will mark the scalar, array, or hash it points to as
- being Readonly as well, and it will recursively traverse the
- structure, marking the whole thing as Readonly. Usually, this is what
- you want. However, if you want only the hash `%h` itself marked as
- Readonly, use `Hash1`.
+ If any of the values is a reference to a scalar, array, or hash, then this
+ function will mark the scalar, array, or hash it points to as being Readonly
+ as well, and it will recursively traverse the structure, marking the whole
+ thing as Readonly. Usually, this is what you want. However, if you want only
+ the hash `%h` itself marked as Readonly, use `Hash1`.
- If %h is already a Readonly variable, the program will die with
- an error about reassigning Readonly variables.
+ If `%h` is already a Readonly variable, the program will die with an error
+ about reassigning Readonly variables.
- Readonly $var => $value;
- Readonly @arr => (value, value, ...);
- Readonly %h => (key => value, ...);
- Readonly %h => {key => value, ...};
- The `Readonly` function is an alternate to the `Scalar`, `Array`,
- and `Hash` functions. It has the advantage (if you consider it an
- advantage) of being one function. That may make your program look
- neater, if you're initializing a whole bunch of constants at once.
- You may or may not prefer this uniform style.
+ The `Readonly` function is an alternate to the `Scalar`, `Array`, and
+ `Hash` functions. It has the advantage (if you consider it an advantage) of
+ being one function. That may make your program look neater, if you're
+ initializing a whole bunch of constants at once. You may or may not prefer
+ this uniform style.
It has the disadvantage of having a slightly different syntax for
versions of Perl prior to 5.8. For earlier versions, you must supply
@@ -256,8 +240,8 @@ production:
- Readonly::Hash1 %h => (key => value, key => value, ...);
- Readonly::Hash1 %h => {key => value, key => value, ...};
- These alternate functions create shallow Readonly variables, instead
- of deep ones. For example:
+ These alternate functions create shallow Readonly variables, instead of deep
+ ones. For example:
Readonly::Array1 @shal => (1, 2, {perl=>'Rules', java=>'Bites'}, 4, 5);
Readonly::Array @deep => (1, 2, {perl=>'Rules', java=>'Bites'}, 4, 5);
@@ -331,10 +315,47 @@ program's namespace by default. The following symbols are also available for
import into your program, if you like: `Scalar`, `Scalar1`, `Array`,
`Array1`, `Hash`, and `Hash1`.
+# Internals
+
+Some people simply do not understand the relationship between this module and
+Readonly::XS so I'm adding this section. Odds are, they still won't understand
+but I like to write so...
+
+In the past, Readonly's "magic" was performed by `tie()`-ing variables to the
+`Readonly::Scalar`, `Readonly::Array`, and `Readonly::Hash` packages (not
+to be confused with the functions of the same names) and acting on `WRITE`,
+`READ`, et. al. While this worked well, it was slow. Very slow. Like 20-30
+times slower than accessing variables directly or using one of the other
+const-related modules that have cropped up since Readonly was released in
+2003.
+
+To 'fix' this, Readonly::XS was written. If installed, Readonly::XS used the
+internal methods `SvREADONLY` and `SvREADONLY_on` to lock simple scalars. On
+the surface, everything was peachy but things weren't the same behind the
+scenes. In edge cases, code perfromed very differently if Readonly::XS was
+installed and because it wasn't a required dependancy in most code, it made
+downstream bugs very hard to track.
+
+In the years since Readonly::XS was released, the then private internal
+methods have been exposed and can be used in pure perl. Similar modules were
+written to take advantage of this and a patch to Readonly was created. We no
+longer need to build and install another module to make Readonly useful on
+modern builds of perl.
+
+- You do not need to install Readonly::XS.
+- You should stop listing Readonly::XS as a dependancy or expect it to
+be installed.
+- Stop testing the `$Readonly::XSokay` variable!
+
# Requirements
-[Readonly::XS](https://metacpan.org/pod/Readonly::XS) is recommended but not required. There are no non-core
-requirements.
+Please note that most users of Readonly no longer need to install the
+companion module Readonly::XS which is recommended but not required for perl
+5.6.x and under. Please do not force it as a requirement in new code and do
+not use the package variable `$Readonly::XSokay` in code/tests. For more, see
+["Internals" in the section on Readonly's new internals](https://metacpan.org/pod/the section on Readonly's new internals#Internals).
+
+There are no non-core requirements.
# Bug Reports
@@ -366,7 +387,7 @@ Original author: Eric J. Roode, roode at cpan.org
# License and Legal
-Copyright (C) 2013 by Sanko Robinson <sanko at cpan.org>
+Copyright (C) 2013, 2014 by Sanko Robinson <sanko at cpan.org>
Copyright (c) 2001-2004 by Eric J. Roode. All Rights Reserved.
diff --git a/cpanfile b/cpanfile
index 0498e4a..2b33866 100644
--- a/cpanfile
+++ b/cpanfile
@@ -1,5 +1,4 @@
-recommends 'Readonly::XS', '1.06';
-recommends 'perl', '5.10.0';
+recommends 'perl', '5.20.0';
requires 'perl', '5.6.0';
test_requires 'Test::More';
diff --git a/eg/benchmark.pl b/eg/benchmark.pl
index c7ed0b5..604d694 100644
--- a/eg/benchmark.pl
+++ b/eg/benchmark.pl
@@ -1,89 +1,83 @@
#!/usr/bin/perl
-
# Very simple benchmark script to show how slow Readonly.pm is,
# and how Readonly::XS solves the problem.
-
use strict;
+use lib '../lib';
use Readonly;
use Benchmark;
-
use vars qw/$feedme/;
-
#
# use constant
#
use constant CONST_LINCOLN => 'Fourscore and seven years ago...';
-sub const
-{
+
+sub const {
$feedme = CONST_LINCOLN;
}
-
#
# literal constant
#
-sub literal
-{
+sub literal {
$feedme = 'Fourscore and seven years ago...';
}
-
#
# typeglob constant
#
use vars qw/$glob_lincoln/;
-*glob_lincoln = \ 'Fourscore and seven years ago...';
-sub tglob
-{
+*glob_lincoln = \'Fourscore and seven years ago...';
+
+sub tglob {
$feedme = $glob_lincoln;
}
-
#
# Normal perl read/write scalar
#
use vars qw/$norm_lincoln/;
$norm_lincoln = 'Fourscore and seven years ago...';
-sub normal
-{
+
+sub normal {
$feedme = $norm_lincoln;
}
-
#
-# Readonly.pm with Readonly::XS
+# Readonly.pm with verbose API
#
-use vars qw/$roxs_lincoln/;
-Readonly::Scalar $roxs_lincoln => 'Fourscore and seven years ago...';
-sub roxs
-{
- $feedme = $roxs_lincoln;
+use vars qw/$ro_lincoln/;
+Readonly::Scalar $ro_lincoln => 'Fourscore and seven years ago...';
+
+sub ro {
+ $feedme = $ro_lincoln;
}
+#
+# Readonly.pm with simple API
+#
+use vars qw/$ro_simple_lincoln/;
+Readonly $ro_simple_lincoln => 'Fourscore and seven years ago...';
+sub ro_simple {
+ $feedme = $ro_simple_lincoln;
+}
#
# Readonly.pm w/o Readonly::XS
#
-use vars qw/$ro_lincoln/;
+use vars qw/$rotie_lincoln/;
{
local $Readonly::XSokay = 0; # disable XS
- Readonly::Scalar $ro_lincoln => 'Fourscore and seven years ago...';
-}
-sub ro
-{
- $feedme = $ro_lincoln;
+ Readonly::Scalar $rotie_lincoln => 'Fourscore and seven years ago...';
}
-
-my $code =
-{
- const => \&const,
- literal => \&literal,
- tglob => \&tglob,
- normal => \&normal,
- roxs => \&roxs,
- ro => \&ro,
+sub rotie {
+ $feedme = $rotie_lincoln;
+}
+my $code = {const => \&const,
+ literal => \&literal,
+ tglob => \&tglob,
+ normal => \&normal,
+ ro => \&ro,
+ ro_simple => \&ro_simple,
+ rotie => \&rotie,
};
-
-unless ($Readonly::XSokay)
-{
+unless ($Readonly::XSokay) {
print "Readonly::XS module not found; skipping that test.\n";
delete $code->{roxs};
}
-
timethese(2_000_000, $code);
diff --git a/lib/Readonly.pm b/lib/Readonly.pm
index 6487eb4..938713a 100644
--- a/lib/Readonly.pm
+++ b/lib/Readonly.pm
@@ -1,15 +1,14 @@
package Readonly;
-use 5.006;
use strict;
#use warnings;
-#no warnings 'uninitialized';
use Exporter;
use vars qw/@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS/;
push @ISA, 'Exporter';
push @EXPORT, qw/Readonly/;
push @EXPORT_OK, qw/Scalar Array Hash Scalar1 Array1 Hash1/;
-our $VERSION = '1.04';
+our $VERSION = 'v1.500.0';
+$VERSION = eval $VERSION;
# Autocroak (Thanks, MJD)
# Only load Carp.pm if module is croaking.
@@ -18,24 +17,140 @@ sub croak {
goto &Carp::croak;
}
-# These functions may be overridden by Readonly::XS, if installed.
-sub is_sv_readonly ($) {0}
-sub make_sv_readonly ($) { die "make_sv_readonly called but not overridden" }
-use vars qw/$XSokay/; # Set to true in Readonly::XS, if available
-
# Common error messages, or portions thereof
use vars qw/$MODIFY $REASSIGN $ODDHASH/;
$MODIFY = 'Modification of a read-only value attempted';
$REASSIGN = 'Attempt to reassign a readonly';
$ODDHASH = 'May not store an odd number of values in a hash';
+use vars qw/$XSokay/; # Set to true in Readonly::XS, if available
+
+# For perl 5.8.x or higher
+# These functions are exposed in perl 5.8.x (Thanks, Leon!)
+# They may be overridden by Readonly::XS, if installed on old perl versions
+if ($] < 5.008) { # 'Classic' perl
+ *is_sv_readonly = sub ($) {0};
+ *make_sv_readonly
+ = sub ($) { die "make_sv_readonly called but not overridden" };
+
+ # See if we can use the XS stuff.
+ $Readonly::XS::MAGIC_COOKIE
+ = "Do NOT use or require Readonly::XS unless you're me.";
+ eval 'use Readonly::XS';
+}
+else { # Modern perl doesn't need Readonly::XS
+ *is_sv_readonly = sub ($) { Internals::SvREADONLY($_[0]) };
+ *make_sv_readonly
+ = sub ($) { Internals::SvREADONLY($_[0], 1) };
+ $XSokay = 1; # We're using the new built-ins so this is a white lie
+}
+
+# Include specialized tie modules for 'Classic' perl
+{
+
+ package Readonly::Array;
+ our $VERSION = '1.05';
+
+ sub TIEARRAY {
+ my $whence
+ = (caller 1)[3]
+ ; # Check if naughty user is trying to tie directly.
+ Readonly::croak "Invalid tie" unless $whence =~ /^Readonly::Array1?$/;
+ my $class = shift;
+ my @self = @_;
+ return bless \@self, $class;
+ }
+
+ sub FETCH {
+ my $self = shift;
+ my $index = shift;
+ return $self->[$index];
+ }
+
+ sub FETCHSIZE {
+ my $self = shift;
+ return scalar @$self;
+ }
+
+ BEGIN {
+ eval q{
+ sub EXISTS {
+ my $self = shift;
+ my $index = shift;
+ return exists $self->[$index];
+ }
+ } if $] >= 5.006; # couldn't do "exists" on arrays before then
+ }
+ *STORE = *STORESIZE = *EXTEND = *PUSH = *POP = *UNSHIFT = *SHIFT = *SPLICE
+ = *CLEAR = *UNTIE = sub { Readonly::croak $Readonly::MODIFY};
+}
+{
+
+ package Readonly::Hash;
+ our $VERSION = '1.05';
+
+ sub TIEHASH {
+ my $whence
+ = (caller 1)[3]
+ ; # Check if naughty user is trying to tie directly.
+ Readonly::croak "Invalid tie" unless $whence =~ /^Readonly::Hash1?$/;
+ my $class = shift;
+
+ # must have an even number of values
+ Readonly::croak $Readonly::ODDHASH unless (@_ % 2 == 0);
+ my %self = @_;
+ return bless \%self, $class;
+ }
+
+ sub FETCH {
+ my $self = shift;
+ my $key = shift;
+ return $self->{$key};
+ }
+
+ sub EXISTS {
+ my $self = shift;
+ my $key = shift;
+ return exists $self->{$key};
+ }
+
+ sub FIRSTKEY {
+ my $self = shift;
+ my $dummy = keys %$self;
+ return scalar each %$self;
+ }
-# See if we can use the XS stuff.
-eval 'use Readonly::XS';
+ sub NEXTKEY {
+ my $self = shift;
+ return scalar each %$self;
+ }
+ *STORE = *DELETE = *CLEAR = *UNTIE
+ = sub { Readonly::croak $Readonly::MODIFY};
+}
+{
-# Include specialized tie modules
-require Readonly::Array;
-require Readonly::Hash;
-require Readonly::Scalar;
+ package Readonly::Scalar;
+ our $VERSION = '1.05';
+
+ sub TIESCALAR {
+ my $whence
+ = (caller 2)[3]
+ ; # Check if naughty user is trying to tie directly.
+ Readonly::croak "Invalid tie"
+ unless $whence && $whence =~ /^Readonly::(?:Scalar1?|Readonly)$/;
+ my $class = shift;
+ Readonly::croak "No value specified for readonly scalar" unless @_;
+ Readonly::croak "Too many values specified for readonly scalar"
+ unless @_ == 1;
+ my $value = shift;
+ return bless \$value, $class;
+ }
+
+ sub FETCH {
+ my $self = shift;
+ return $$self;
+ }
+ *STORE = *UNTIE = sub { Readonly::croak $Readonly::MODIFY};
+}
# Predeclare the following, so we can use them recursively
sub Scalar ($$);
@@ -52,14 +167,14 @@ sub _is_badtype {
# Shallow Readonly scalar
sub Scalar1 ($$) {
- croak "$REASSIGN scalar" if is_sv_readonly $_[0];
+ croak "$REASSIGN scalar" if is_sv_readonly($_[0]);
my $badtype = _is_badtype(ref tied $_[0]);
croak "$REASSIGN $badtype" if $badtype;
# xs method: flag scalar as readonly
if ($XSokay) {
$_[0] = $_[1];
- make_sv_readonly $_[0];
+ make_sv_readonly($_[0]);
return;
}
@@ -98,7 +213,7 @@ sub Hash1 (\%;@) {
# Deep Readonly scalar
sub Scalar ($$) {
- croak "$REASSIGN scalar" if is_sv_readonly $_[0];
+ croak "$REASSIGN scalar" if is_sv_readonly($_[0]);
my $badtype = _is_badtype(ref tied $_[0]);
croak "$REASSIGN $badtype" if $badtype;
my $value = $_[1];
@@ -113,7 +228,7 @@ sub Scalar ($$) {
# xs method: flag scalar as readonly
if ($XSokay) {
$_[0] = $value;
- make_sv_readonly $_[0];
+ make_sv_readonly($_[0]);
return;
}
@@ -169,40 +284,28 @@ sub Hash (\%;@) {
}
# Common entry-point for all supported data types
-eval q{sub Readonly} . ($] < 5.008 ? '' : '(\[$@%]@)') . <<'SUB_READONLY';
-{
- if (ref $_[0] eq 'SCALAR') {
- croak $MODIFY if is_sv_readonly ${$_[0]};
- my $badtype = _is_badtype(ref tied ${$_[0]});
- croak "$REASSIGN $badtype" if $badtype;
- croak "Readonly scalar must have only one value" if @_ > 2;
- my $tieobj = eval { tie ${$_[0]}, 'Readonly::Scalar', $_[1] };
-
-# Tie may have failed because user tried to tie a constant, or we screwed up somehow.
- if ($@) {
- croak $MODIFY
- if $@ =~ /^$MODIFY at/; # Point the finger at the user.
- die "$@\n"; # Not a modify read-only message; must be our fault.
- }
- return $tieobj;
+eval q{sub Readonly} . ($] < 5.008 ? '' : '(\[$@%]@)') . <<'#SUB_READONLY';
+{ my $ref = shift;
+ my $type = ref $ref;
+ if ((!defined$type) || $type eq 'SCALAR') {
+ croak 'Not enough arguments for Readonly' if $#_ == -1;
+ return Scalar $$ref, shift;
}
- elsif (ref $_[0] eq 'ARRAY') {
- my $aref = shift;
- return Array @$aref, @_;
+ elsif ($type eq 'ARRAY') {
+ return Array @$ref, @_;
}
- elsif (ref $_[0] eq 'HASH') {
- my $href = shift;
- croak $ODDHASH if @_ % 2 != 0 && !(@_ == 1 && ref $_[0] eq 'HASH');
- return Hash %$href, @_;
+ elsif ($type eq 'HASH') {
+ croak $ODDHASH if @_ % 2 != 0 && !(@_ == 1 && $type eq 'HASH');
+ return Hash %$ref, @_;
}
- elsif (ref $_[0]) {
+ elsif ($type) {
croak "Readonly only supports scalar, array, and hash variables.";
}
else {
croak "First argument to Readonly must be a reference.";
}
}
-SUB_READONLY
+#SUB_READONLY
1;
=head1 NAME
@@ -213,15 +316,15 @@ Readonly - Facility for creating read-only scalars, arrays, hashes
use Readonly;
- # Read-only scalar
+ # Deep Read-only scalar
Readonly::Scalar $sca => $initial_value;
Readonly::Scalar my $sca => $initial_value;
- # Read-only array
+ # Deep Read-only array
Readonly::Array @arr => @values;
Readonly::Array my @arr => @values;
- # Read-only hash
+ # Deep Read-only hash
Readonly::Hash %has => (key => value, key => value, ...);
Readonly::Hash my %has => (key => value, key => value, ...);
# or:
@@ -256,23 +359,33 @@ Readonly - Facility for creating read-only scalars, arrays, hashes
=head1 Description
-This is a facility for creating non-modifiable variables. This is useful for
-configuration files, headers, etc. It can also be useful as a development and
-debugging tool, for catching updates to variables that should not be changed.
+This is a facility for creating non-modifiable variables. This is useful for
+configuration files, headers, etc. It can also be useful as a development and
+debugging tool for catching updates to variables that should not be changed.
+
+=head1 Variable Depth
+
+Readonly has the ability to create both deep and shallow readonly variables.
+
+If any of the values you pass to C<Scalar>, C<Array>, C<Hash>, or the standard
+C<Readonly> are references, then those functions recurse over the data
+structures, marking everything as Readonly. The entire structure is
+nonmodifiable. This is normally what you want.
-If any of the values you pass to C<Scalar>, C<Array>, or C<Hash> are
-references, then those functions recurse over the data structures, marking
-everything as Readonly. Usually, this is what you want: the entire structure
-nonmodifiable. If you want only the top level to be Readonly, use the
-alternate C<Scalar1>, C<Array1> and C<Hash1> functions.
+If you want only the top level to be Readonly, use the alternate (and poorly
+named) C<Scalar1>, C<Array1>, and C<Hash1> functions.
-Please note that most users of Readonly will also want to install a companion
-module Readonly::XS. See the L</Cons> section below for more details.
+=head1
-=head1 Comparison with "use constant"
+=head1 The Past
+
+The following sections are updated versions of the previous authors
+documentation.
+
+=head2 Comparison with "use constant"
Perl provides a facility for creating constant values, via the L<constant>
-pragma. There are several problems with this pragma.
+pragma. There are several problems with this pragma.
=over 2
@@ -295,11 +408,11 @@ For example:
$some_value = $hash{SOME_KEY}; # wrong!
$some_value = $hash{+SOME_KEY}; # right
-(who thinks to use a unary plus when using a hash?)
+(who thinks to use a unary plus when using a hash to scalarize the key?)
=item * C<use constant> works for scalars and arrays, not hashes.
-=item * These constants are global ot the package in which they're declared;
+=item * These constants are global to the package in which they're declared;
cannot be lexically scoped.
=item * Works only at compile time.
@@ -319,72 +432,48 @@ structures) with C<use constant>.
=head1 Comparison with typeglob constants
-Another popular way to create read-only scalars is to modify the symbol
-table entry for the variable by using a typeglob:
+Another popular way to create read-only scalars is to modify the symbol table
+entry for the variable by using a typeglob:
*a = \'value';
-This works fine, but it only works for global variables ("my"
-variables have no symbol table entry). Also, the following similar
-constructs do B<not> work:
+This works fine, but it only works for global variables ("my" variables have
+no symbol table entry). Also, the following similar constructs do B<not> work:
*a = [1, 2, 3]; # Does NOT create a read-only array
*a = { a => 'A'}; # Does NOT create a read-only hash
-=head1 Pros
+=head2 Pros
-Readonly.pm, on the other hand, will work with global variables and
-with lexical ("my") variables. It will create scalars, arrays, or
-hashes, all of which look and work like normal, read-write Perl
-variables. You can use them in scalar context, in list context; you
-can take references to them, pass them to functions, anything.
+Readonly.pm, on the other hand, will work with global variables and with
+lexical ("my") variables. It will create scalars, arrays, or hashes, all of
+which look and work like normal, read-write Perl variables. You can use them
+in scalar context, in list context; you can take references to them, pass them
+to functions, anything.
-Readonly.pm also works well with complex data structures, allowing you
-to tag the whole structure as nonmodifiable, or just the top level.
+Readonly.pm also works well with complex data structures, allowing you to tag
+the whole structure as nonmodifiable, or just the top level.
-Also, Readonly variables may not be reassigned. The following code will die:
+Also, Readonly variables may not be reassigned. The following code will die:
Readonly::Scalar $pi => 3.14159;
...
Readonly::Scalar $pi => 2.71828;
-=head1 Cons
-
-Readonly.pm does impose a performance penalty. It's pretty slow. How
-slow? Run the C<eg/benchmark.pl> script that comes with Readonly. On my
-test system, "use constant", typeglob constants, and regular
-read/write Perl variables were all about the same speed, and
-Readonly.pm constants were about 1/20 the speed.
-
-However, there is relief. There is a companion module available,
-Readonly::XS. If it is installed on your system, Readonly.pm uses it
-to make read-only scalars much faster. With Readonly::XS, Readonly
-scalars are as fast as the other types of variables. Readonly arrays
-and hashes will still be relatively slow. But it's likely that most
-of your Readonly variables will be scalars.
-
-If you can't use Readonly::XS (for example, if you don't have a C
-compiler, or your perl is statically linked and you don't want to
-re-link it), you have to decide whether the benefits of Readonly
-variables outweigh the speed issue. For most configuration variables
-(and other things that Readonly is likely to be useful for), the speed
-issue is probably not really a big problem. But benchmark your
-program if it might be. If it turns out to be a problem, you may
-still want to use Readonly.pm during development, to catch changes to
-variables that should not be changed, and then remove it for
-production:
-
- # For testing:
- Readonly::Scalar $Foo_Directory => '/usr/local/foo';
- Readonly::Scalar $Bar_Directory => '/usr/local/bar';
- # $Foo_Directory = '/usr/local/foo';
- # $Bar_Directory = '/usr/local/bar';
-
- # For production:
- # Readonly::Scalar $Foo_Directory => '/usr/local/foo';
- # Readonly::Scalar $Bar_Directory => '/usr/local/bar';
- $Foo_Directory = '/usr/local/foo';
- $Bar_Directory = '/usr/local/bar';
+=head2 Cons
+
+Readonly.pm used to impose a performance penalty. It was pretty slow. How
+slow? Run the C<eg/benchmark.pl> script that comes with Readonly. On my test
+system, "use constant" (const), typeglob constants (tglob), regular read/write
+Perl variables (normal/literal), and the new Readonly (ro/ro_simple) are all
+about the same speed, the old, tie based Readonly.pm constants were about 1/22
+the speed.
+
+However, there is relief. There is a companion module available, Readonly::XS.
+You won't need this if you're using Perl 5.8.x or higher.
+
+I repeat, you do not need Readonly::XS if your environment has perl 5.8.x or
+higher. Please see section entitled L<Internals|/"Internals"> for more.
=head1 Functions
@@ -392,62 +481,59 @@ production:
=item Readonly::Scalar $var => $value;
-Creates a nonmodifiable scalar, C<$var>, and assigns a value of
-C<$value> to it. Thereafter, its value may not be changed. Any
-attempt to modify the value will cause your program to die.
+Creates a nonmodifiable scalar, C<$var>, and assigns a value of C<$value> to
+it. Thereafter, its value may not be changed. Any attempt to modify the value
+will cause your program to die.
-A value I<must> be supplied. If you want the variable to have
-C<undef> as its value, you must specify C<undef>.
+A value I<must> be supplied. If you want the variable to have C<undef> as its
+value, you must specify C<undef>.
-If C<$value> is a reference to a scalar, array, or hash, then this
-function will mark the scalar, array, or hash it points to as being
-Readonly as well, and it will recursively traverse the structure,
-marking the whole thing as Readonly. Usually, this is what you want.
-However, if you want only the C<$value> marked as Readonly, use
-C<Scalar1>.
+If C<$value> is a reference to a scalar, array, or hash, then this function
+will mark the scalar, array, or hash it points to as being Readonly as well,
+and it will recursively traverse the structure, marking the whole thing as
+Readonly. Usually, this is what you want. However, if you want only the
+C<$value> marked as Readonly, use C<Scalar1>.
-If $var is already a Readonly variable, the program will die with
-an error about reassigning Readonly variables.
+If $var is already a Readonly variable, the program will die with an error
+about reassigning Readonly variables.
=item Readonly::Array @arr => (value, value, ...);
-Creates a nonmodifiable array, C<@arr>, and assigns the specified list
-of values to it. Thereafter, none of its values may be changed; the
-array may not be lengthened or shortened or spliced. Any attempt to
-do so will cause your program to die.
+Creates a nonmodifiable array, C<@arr>, and assigns the specified list of
+values to it. Thereafter, none of its values may be changed; the array may not
+be lengthened or shortened or spliced. Any attempt to do so will cause your
+program to die.
-If any of the values passed is a reference to a scalar, array, or hash,
-then this function will mark the scalar, array, or hash it points to as
-being Readonly as well, and it will recursively traverse the structure,
-marking the whole thing as Readonly. Usually, this is what you want.
-However, if you want only the hash C<%@arr> itself marked as Readonly,
-use C<Array1>.
+If any of the values passed is a reference to a scalar, array, or hash, then
+this function will mark the scalar, array, or hash it points to as being
+Readonly as well, and it will recursively traverse the structure, marking the
+whole thing as Readonly. Usually, this is what you want. However, if you want
+only the hash C<%@arr> itself marked as Readonly, use C<Array1>.
-If @arr is already a Readonly variable, the program will die with
-an error about reassigning Readonly variables.
+If C<@arr> is already a Readonly variable, the program will die with an error
+about reassigning Readonly variables.
=item Readonly::Hash %h => (key => value, key => value, ...);
=item Readonly::Hash %h => {key => value, key => value, ...};
-Creates a nonmodifiable hash, C<%h>, and assigns the specified keys
-and values to it. Thereafter, its keys or values may not be changed.
-Any attempt to do so will cause your program to die.
+Creates a nonmodifiable hash, C<%h>, and assigns the specified keys and values
+to it. Thereafter, its keys or values may not be changed. Any attempt to do so
+will cause your program to die.
-A list of keys and values may be specified (with parentheses in the
-synopsis above), or a hash reference may be specified (curly braces in
-the synopsis above). If a list is specified, it must have an even
-number of elements, or the function will die.
+A list of keys and values may be specified (with parentheses in the synopsis
+above), or a hash reference may be specified (curly braces in the synopsis
+above). If a list is specified, it must have an even number of elements, or
+the function will die.
-If any of the values is a reference to a scalar, array, or hash, then
-this function will mark the scalar, array, or hash it points to as
-being Readonly as well, and it will recursively traverse the
-structure, marking the whole thing as Readonly. Usually, this is what
-you want. However, if you want only the hash C<%h> itself marked as
-Readonly, use C<Hash1>.
+If any of the values is a reference to a scalar, array, or hash, then this
+function will mark the scalar, array, or hash it points to as being Readonly
+as well, and it will recursively traverse the structure, marking the whole
+thing as Readonly. Usually, this is what you want. However, if you want only
+the hash C<%h> itself marked as Readonly, use C<Hash1>.
-If %h is already a Readonly variable, the program will die with
-an error about reassigning Readonly variables.
+If C<%h> is already a Readonly variable, the program will die with an error
+about reassigning Readonly variables.
=item Readonly $var => $value;
@@ -457,11 +543,11 @@ an error about reassigning Readonly variables.
=item Readonly %h => {key => value, ...};
-The C<Readonly> function is an alternate to the C<Scalar>, C<Array>,
-and C<Hash> functions. It has the advantage (if you consider it an
-advantage) of being one function. That may make your program look
-neater, if you're initializing a whole bunch of constants at once.
-You may or may not prefer this uniform style.
+The C<Readonly> function is an alternate to the C<Scalar>, C<Array>, and
+C<Hash> functions. It has the advantage (if you consider it an advantage) of
+being one function. That may make your program look neater, if you're
+initializing a whole bunch of constants at once. You may or may not prefer
+this uniform style.
It has the disadvantage of having a slightly different syntax for
versions of Perl prior to 5.8. For earlier versions, you must supply
@@ -482,8 +568,8 @@ You may or may not consider this ugly.
=item Readonly::Hash1 %h => {key => value, key => value, ...};
-These alternate functions create shallow Readonly variables, instead
-of deep ones. For example:
+These alternate functions create shallow Readonly variables, instead of deep
+ones. For example:
Readonly::Array1 @shal => (1, 2, {perl=>'Rules', java=>'Bites'}, 4, 5);
Readonly::Array @deep => (1, 2, {perl=>'Rules', java=>'Bites'}, 4, 5);
@@ -559,10 +645,53 @@ program's namespace by default. The following symbols are also available for
import into your program, if you like: C<Scalar>, C<Scalar1>, C<Array>,
C<Array1>, C<Hash>, and C<Hash1>.
+=head1 Internals
+
+Some people simply do not understand the relationship between this module and
+Readonly::XS so I'm adding this section. Odds are, they still won't understand
+but I like to write so...
+
+In the past, Readonly's "magic" was performed by C<tie()>-ing variables to the
+C<Readonly::Scalar>, C<Readonly::Array>, and C<Readonly::Hash> packages (not
+to be confused with the functions of the same names) and acting on C<WRITE>,
+C<READ>, et. al. While this worked well, it was slow. Very slow. Like 20-30
+times slower than accessing variables directly or using one of the other
+const-related modules that have cropped up since Readonly was released in
+2003.
+
+To 'fix' this, Readonly::XS was written. If installed, Readonly::XS used the
+internal methods C<SvREADONLY> and C<SvREADONLY_on> to lock simple scalars. On
+the surface, everything was peachy but things weren't the same behind the
+scenes. In edge cases, code perfromed very differently if Readonly::XS was
+installed and because it wasn't a required dependancy in most code, it made
+downstream bugs very hard to track.
+
+In the years since Readonly::XS was released, the then private internal
+methods have been exposed and can be used in pure perl. Similar modules were
+written to take advantage of this and a patch to Readonly was created. We no
+longer need to build and install another module to make Readonly useful on
+modern builds of perl.
+
+=over
+
+=item * You do not need to install Readonly::XS.
+
+=item * You should stop listing Readonly::XS as a dependancy or expect it to
+be installed.
+
+=item * Stop testing the C<$Readonly::XSokay> variable!
+
+=back
+
=head1 Requirements
-L<Readonly::XS> is recommended but not required. There are no non-core
-requirements.
+Please note that most users of Readonly no longer need to install the
+companion module Readonly::XS which is recommended but not required for perl
+5.6.x and under. Please do not force it as a requirement in new code and do
+not use the package variable C<$Readonly::XSokay> in code/tests. For more, see
+L<the section on Readonly's new internals/Internals>.
+
+There are no non-core requirements.
=head1 Bug Reports
@@ -594,7 +723,7 @@ Original author: Eric J. Roode, roode at cpan.org
=head1 License and Legal
-Copyright (C) 2013 by Sanko Robinson <sanko at cpan.org>
+Copyright (C) 2013, 2014 by Sanko Robinson <sanko at cpan.org>
Copyright (c) 2001-2004 by Eric J. Roode. All Rights Reserved.
diff --git a/lib/Readonly/Array.pm b/lib/Readonly/Array.pm
deleted file mode 100644
index 218c7de..0000000
--- a/lib/Readonly/Array.pm
+++ /dev/null
@@ -1,34 +0,0 @@
-package Readonly::Array;
-our $VERSION = '1.04';
-
-sub TIEARRAY {
- my $whence
- = (caller 1)[3]; # Check if naughty user is trying to tie directly.
- Readonly::croak "Invalid tie" unless $whence =~ /^Readonly::Array1?$/;
- my $class = shift;
- my @self = @_;
- return bless \@self, $class;
-}
-
-sub FETCH {
- my $self = shift;
- my $index = shift;
- return $self->[$index];
-}
-
-sub FETCHSIZE {
- my $self = shift;
- return scalar @$self;
-}
-
-BEGIN {
- eval q{
- sub EXISTS {
- my $self = shift;
- my $index = shift;
- return exists $self->[$index];
- }
- } if $] >= 5.006; # couldn't do "exists" on arrays before then
-}
-*STORE = *STORESIZE = *EXTEND = *PUSH = *POP = *UNSHIFT = *SHIFT = *SPLICE
- = *CLEAR = *UNTIE = sub { Readonly::croak $Readonly::MODIFY};
diff --git a/lib/Readonly/Hash.pm b/lib/Readonly/Hash.pm
deleted file mode 100644
index 548a64f..0000000
--- a/lib/Readonly/Hash.pm
+++ /dev/null
@@ -1,38 +0,0 @@
-package Readonly::Hash;
-our $VERSION = '1.04';
-
-sub TIEHASH {
- my $whence
- = (caller 1)[3]; # Check if naughty user is trying to tie directly.
- Readonly::croak "Invalid tie" unless $whence =~ /^Readonly::Hash1?$/;
- my $class = shift;
-
- # must have an even number of values
- Readonly::croak $Readonly::ODDHASH unless (@_ % 2 == 0);
- my %self = @_;
- return bless \%self, $class;
-}
-
-sub FETCH {
- my $self = shift;
- my $key = shift;
- return $self->{$key};
-}
-
-sub EXISTS {
- my $self = shift;
- my $key = shift;
- return exists $self->{$key};
-}
-
-sub FIRSTKEY {
- my $self = shift;
- my $dummy = keys %$self;
- return scalar each %$self;
-}
-
-sub NEXTKEY {
- my $self = shift;
- return scalar each %$self;
-}
-*STORE = *DELETE = *CLEAR = *UNTIE = sub { Readonly::croak $Readonly::MODIFY};
diff --git a/lib/Readonly/Scalar.pm b/lib/Readonly/Scalar.pm
deleted file mode 100644
index a62095e..0000000
--- a/lib/Readonly/Scalar.pm
+++ /dev/null
@@ -1,21 +0,0 @@
-package Readonly::Scalar;
-our $VERSION = '1.04';
-
-sub TIESCALAR {
- my $whence
- = (caller 2)[3]; # Check if naughty user is trying to tie directly.
- Readonly::croak "Invalid tie"
- unless $whence && $whence =~ /^Readonly::(?:Scalar1?|Readonly)$/;
- my $class = shift;
- Readonly::croak "No value specified for readonly scalar" unless @_;
- Readonly::croak "Too many values specified for readonly scalar"
- unless @_ == 1;
- my $value = shift;
- return bless \$value, $class;
-}
-
-sub FETCH {
- my $self = shift;
- return $$self;
-}
-*STORE = *UNTIE = sub { Readonly::croak $Readonly::MODIFY};
diff --git a/t/docs.t b/t/general/docs.t
similarity index 99%
rename from t/docs.t
rename to t/general/docs.t
index 24156e7..6c0fdc7 100644
--- a/t/docs.t
+++ b/t/general/docs.t
@@ -1,4 +1,4 @@
-#!perl -I..
+#!perl -I../../lib
# Examples from the docs -- make sure they work!
use strict;
use Test::More tests => 22;
diff --git a/t/export.t b/t/general/export.t
similarity index 89%
rename from t/export.t
rename to t/general/export.t
index 9329e7c..ba402f9 100644
--- a/t/export.t
+++ b/t/general/export.t
@@ -1,4 +1,4 @@
-#!perl -I..
+#!perl -I../../lib
# Readonly hash tests
use strict;
use Test::More tests => 1;
diff --git a/t/tie.t b/t/general/tie.t
similarity index 96%
rename from t/tie.t
rename to t/general/tie.t
index 7f9765c..c8219d7 100644
--- a/t/tie.t
+++ b/t/general/tie.t
@@ -1,4 +1,4 @@
-#!perl -I..
+#!perl -I../../lib
# Test the Readonly function
use strict;
use Test::More tests => 4;
diff --git a/t/array.t b/t/simple_api/array.t
similarity index 92%
copy from t/array.t
copy to t/simple_api/array.t
index 78c12ba..5773e04 100644
--- a/t/array.t
+++ b/t/simple_api/array.t
@@ -1,4 +1,4 @@
-#!perl -I..
+#!perl -I../../lib
# Readonly array tests
use strict;
use Test::More tests => 23;
@@ -16,11 +16,11 @@ use vars qw/@a1 @a2/;
my @ma1;
# creation (3 tests)
-eval 'Readonly::Array @a1;';
+eval 'Readonly @a1;';
is $@ => '', 'Create empty global array';
-eval 'Readonly::Array @ma1 => ();';
+eval 'Readonly @ma1 => ();';
is $@ => '', 'Create empty lexical array';
-eval 'Readonly::Array @a2 => (1,2,3,4,5);';
+eval 'Readonly @a2 => (1,2,3,4,5);';
is $@ => '', 'Create global array';
# fetching (3 tests)
@@ -81,6 +81,8 @@ is $@ => expected(__LINE__- 1), 'Splice';
# untie (1 test)
SKIP: {
skip "Can't catch untie until Perl 5.6", 1 if $] <= 5.006;
+ skip "Don't use tie on Perl 5.8.x+", 1 if $] >= 5.008;
+
eval { untie @a2; };
is $@ => expected(__LINE__- 1), 'Untie';
}
diff --git a/t/hash.t b/t/simple_api/hash.t
similarity index 86%
copy from t/hash.t
copy to t/simple_api/hash.t
index 0af2cfa..8193fd6 100644
--- a/t/hash.t
+++ b/t/simple_api/hash.t
@@ -1,4 +1,4 @@
-#!perl -I..
+#!perl -I../../lib
# Readonly hash tests
use strict;
use Test::More tests => 20;
@@ -16,11 +16,11 @@ use vars qw/%h1/;
my (%mh1, %mh2);
# creation (3 tests)
-eval { Readonly::Hash %h1 => (a => "A", b => "B", c => "C", d => "D") };
+eval { Readonly %h1 => (a => "A", b => "B", c => "C", d => "D") };
is $@ => '', 'Create global hash';
-eval { Readonly::Hash %mh1 => (one => 1, two => 2, three => 3, 4) };
+eval { Readonly %mh1 => (one => 1, two => 2, three => 3, 4) };
like $@ => qr/odd number of values/, "Odd number of values";
-eval { Readonly::Hash %mh1 => {one => 1, two => 2, three => 3, four => 4} };
+eval { Readonly %mh1 => {one => 1, two => 2, three => 3, four => 4} };
is $@ => '', 'Create lexical hash';
# fetch (3 tests)
diff --git a/t/readonly.t b/t/simple_api/readonly.t
similarity index 72%
copy from t/readonly.t
copy to t/simple_api/readonly.t
index f18e347..0e16ce5 100644
--- a/t/readonly.t
+++ b/t/simple_api/readonly.t
@@ -1,18 +1,24 @@
-#!perl -I..
+#!perl -I../../lib
# Test the Readonly function
use strict;
-use Test::More tests => 19;
+use Test::More tests => 23;
# Find the module (1 test)
BEGIN { use_ok('Readonly'); }
my $expected
= qr/Modification of a read-only value attempted at \(eval \d+\),? line 1/;
SKIP:
-{ skip 'Readonly \\ syntax is for perls earlier than 5.8', 9 if $] >= 5.008;
+{ skip 'Readonly \\ syntax is for perls earlier than 5.8', 11
+ if $] >= 5.008;
eval q{Readonly \my $ros => 45};
is $@ => '', 'Create scalar';
eval q{Readonly \my $ros2 => 45; $ros2 = 45};
like $@ => $expected, 'Modify scalar';
+ eval q{Readonly \my $roaref => [1, 2, 3, 4]; $roaref->[2] = 3};
+ like $@ => $expected, 'Modify scalar array reference';
+ eval
+ q{Readonly \my $rohref => { key1 => "value", key2 => "value2" }; $rohref->{key1} = "value"};
+ like $@ => $expected, 'Modify scalar hash reference';
eval q{Readonly \my @roa => (1, 2, 3, 4)};
is $@ => '', 'Create array';
eval q{Readonly \my @roa2 => (1, 2, 3, 4); $roa2[2] = 3};
@@ -31,11 +37,17 @@ SKIP:
like $@ => $expected, 'Modify hash';
}
SKIP:
-{ skip 'Readonly $@% syntax is for perl 5.8 or later', 9 unless $] >= 5.008;
+{ skip 'Readonly $@% syntax is for perl 5.8 or later', 11
+ unless $] >= 5.008;
eval q{Readonly my $ros => 45};
is $@ => '', 'Create scalar';
eval q{Readonly my $ros2 => 45; $ros2 = 45};
like $@ => $expected, 'Modify scalar';
+ eval q{Readonly my $roaref => [1, 2, 3, 4]; $roaref->[2] = 3};
+ like $@ => $expected, 'Modify scalar array reference';
+ eval
+ q{Readonly my $rohref => { key1 => "value", key2 => "value2" }; $rohref->{key1} = "value"};
+ like $@ => $expected, 'Modify scalar hash reference';
eval q{Readonly my @roa => (1, 2, 3, 4)};
is $@ => '', 'Create array';
eval q{Readonly my @roa2 => (1, 2, 3, 4); $roa2[2] = 3};
diff --git a/t/reassign.t b/t/simple_api/reassign.t
similarity index 76%
copy from t/reassign.t
copy to t/simple_api/reassign.t
index 1e0fcea..9352a3b 100644
--- a/t/reassign.t
+++ b/t/simple_api/reassign.t
@@ -1,4 +1,4 @@
-#!perl -I..
+#!perl -I../../lib
# Readonly reassignment-prevention tests
use strict;
use Test::More tests => 22;
@@ -6,27 +6,27 @@ use Test::More tests => 22;
# Find the module (1 test)
BEGIN { use_ok('Readonly'); }
use vars qw($s1 @a1 %h1 $s2 @a2 %h2);
-Readonly::Scalar $s1 => 'a scalar value';
-Readonly::Array @a1 => 'an', 'array', 'value';
-Readonly::Hash %h1 => {a => 'hash', of => 'things'};
+Readonly $s1 => 'a scalar value';
+Readonly @a1 => 'an', 'array', 'value';
+Readonly %h1 => {a => 'hash', of => 'things'};
my $err = qr/^Attempt to reassign/;
# Reassign scalar
-eval { Readonly::Scalar $s1 => "a second scalar value" };
-like $@ => $err, 'Readonly::Scalar reassign die';
-is $s1 => 'a scalar value', 'Readonly::Scalar reassign no effect';
+eval { Readonly $s1 => "a second scalar value" };
+ok defined $@, 'Readonly reassign die';
+is $s1 => 'a scalar value', 'Readonly reassign no effect';
# Reassign array
-eval { Readonly::Array @a1 => "another", "array" };
-like $@ => $err, 'Readonly::Array reassign die';
+eval { Readonly @a1 => "another", "array" };
+like $@ => $err, 'Readonly reassign die';
ok eq_array(\@a1, [qw[an array value]]) =>
- 'Readonly::Array reassign no effect';
+ 'Readonly reassign no effect';
# Reassign hash
-eval { Readonly::Hash %h1 => "another", "hash" };
-like $@ => $err, 'Readonly::Hash reassign die';
+eval { Readonly %h1 => "another", "hash" };
+like $@ => $err, 'Readonly reassign die';
ok eq_hash(\%h1, {a => 'hash', of => 'things'}) =>
- 'Readonly::Hash reassign no effect';
+ 'Readonly reassign no effect';
# Now use the naked Readonly function
SKIP:
@@ -87,7 +87,7 @@ SKIP:
}
# Reassign real constants
-eval q{Readonly::Scalar "hello" => "goodbye"};
-like $@ => $err, 'Reassign real string';
-eval q{Readonly::Scalar1 6 => 13};
-like $@ => $err, 'Reassign real number';
+eval q{Readonly "hello" => "goodbye"};
+ok defined $@, 'Reassign real string';
+eval q{Readonly 6 => 13};
+ok defined $@, 'Reassign real number';
diff --git a/t/scalar.t b/t/simple_api/scalar.t
similarity index 58%
copy from t/scalar.t
copy to t/simple_api/scalar.t
index 547631f..cefcbd3 100644
--- a/t/scalar.t
+++ b/t/simple_api/scalar.t
@@ -1,7 +1,7 @@
-#!perl -I..
+#!perl -I../../lib
# Readonly scalar tests
use strict;
-use Test::More tests => 12;
+use Test::More tests => 11;
# Find the module (1 test)
BEGIN { use_ok('Readonly'); }
@@ -16,15 +16,14 @@ use vars qw/$s1 $s2/;
my ($ms1, $ms2);
# creation (4 tests)
-eval { Readonly::Scalar $s1 => 13 };
+eval { Readonly $s1 => 13 };
is $@ => '', 'Create a global scalar';
-eval { Readonly::Scalar $ms1 => 31 };
+eval { Readonly $ms1 => 31 };
is $@ => '', 'Create a lexical scalar';
-eval { Readonly::Scalar $s2 => undef };
+eval { Readonly $s2 => undef };
is $@ => '', 'Create an undef global scalar';
-eval 'Readonly::Scalar $ms2'
- ; # must be eval string because it's a compile-time error
-like $@ => qr/^Not enough arguments for Readonly::Scalar/, 'Try w/o args';
+eval 'Readonly $ms2'; # must be eval string because it's a fatal error
+like $@ => qr/^Not enough arguments for Readonly/, 'Try w/o args';
# fetching (4 tests)
is $s1 => 13, 'Fetch global';
@@ -36,11 +35,3 @@ ok !defined $ms2, 'Fetch undef lexical';
eval { $s1 = 7 };
is $@ => expected(__LINE__- 1), 'Error setting global';
is $s1 => 13, 'Readonly global value unchanged';
-
-# untie (1 test)
-SKIP: {
- skip "Can't catch 'untie' until perl 5.6", 1 if $] < 5.006;
- skip "Scalars not tied: XS in use", 1 if $Readonly::XSokay;
- eval { untie $ms1 };
- is $@ => expected(__LINE__- 1), 'Untie';
-}
diff --git a/t/array.t b/t/verbose_api/array.t
similarity index 99%
rename from t/array.t
rename to t/verbose_api/array.t
index 78c12ba..34de962 100644
--- a/t/array.t
+++ b/t/verbose_api/array.t
@@ -1,4 +1,4 @@
-#!perl -I..
+#!perl -I../lib
# Readonly array tests
use strict;
use Test::More tests => 23;
diff --git a/t/deepa.t b/t/verbose_api/deepa.t
similarity index 99%
rename from t/deepa.t
rename to t/verbose_api/deepa.t
index 3e60e14..77d5a12 100644
--- a/t/deepa.t
+++ b/t/verbose_api/deepa.t
@@ -1,4 +1,3 @@
-#!perl -I..
# Test Array vs Array1 functionality
use strict;
use Test::More tests => 13;
diff --git a/t/deeph.t b/t/verbose_api/deeph.t
similarity index 98%
rename from t/deeph.t
rename to t/verbose_api/deeph.t
index 4e8b9da..7f2c106 100644
--- a/t/deeph.t
+++ b/t/verbose_api/deeph.t
@@ -1,4 +1,4 @@
-#!perl -I..
+#!perl -I../lib
# Test Hash vs Hash1 functionality
use strict;
use Test::More tests => 13;
diff --git a/t/deeps.t b/t/verbose_api/deeps.t
similarity index 97%
rename from t/deeps.t
rename to t/verbose_api/deeps.t
index 611a0a6..6a3fedc 100644
--- a/t/deeps.t
+++ b/t/verbose_api/deeps.t
@@ -1,4 +1,4 @@
-#!perl -I..
+#!perl -I../lib
# Test Scalar vs Scalar1 functionality
use strict;
use Test::More tests => 21;
@@ -10,7 +10,7 @@ sub expected {
my $line = shift;
$@ =~ s/\.$//; # difference between croak and die
return "Modification of a read-only value attempted at " . __FILE__
- . " line $line\n";
+ . " line $line\n";
}
use vars qw/$s1 $s2 $s3 $s4/;
my $m1 = 17;
diff --git a/t/hash.t b/t/verbose_api/hash.t
similarity index 99%
rename from t/hash.t
rename to t/verbose_api/hash.t
index 0af2cfa..00bc12b 100644
--- a/t/hash.t
+++ b/t/verbose_api/hash.t
@@ -1,4 +1,4 @@
-#!perl -I..
+#!perl -I../lib
# Readonly hash tests
use strict;
use Test::More tests => 20;
diff --git a/t/readonly.t b/t/verbose_api/readonly.t
similarity index 72%
rename from t/readonly.t
rename to t/verbose_api/readonly.t
index f18e347..c19eb91 100644
--- a/t/readonly.t
+++ b/t/verbose_api/readonly.t
@@ -1,18 +1,24 @@
-#!perl -I..
+#!perl -I../lib
# Test the Readonly function
use strict;
-use Test::More tests => 19;
+use Test::More tests => 23;
# Find the module (1 test)
BEGIN { use_ok('Readonly'); }
my $expected
= qr/Modification of a read-only value attempted at \(eval \d+\),? line 1/;
SKIP:
-{ skip 'Readonly \\ syntax is for perls earlier than 5.8', 9 if $] >= 5.008;
+{ skip 'Readonly \\ syntax is for perls earlier than 5.8', 11
+ if $] >= 5.008;
eval q{Readonly \my $ros => 45};
is $@ => '', 'Create scalar';
eval q{Readonly \my $ros2 => 45; $ros2 = 45};
like $@ => $expected, 'Modify scalar';
+ eval q{Readonly \my $roaref => [1, 2, 3, 4]; $roaref->[2] = 3};
+ like $@ => $expected, 'Modify scalar array reference';
+ eval
+ q{Readonly \my $rohref => { key1 => "value", key2 => "value2" }; $rohref->{key1} = "value"};
+ like $@ => $expected, 'Modify scalar hash reference';
eval q{Readonly \my @roa => (1, 2, 3, 4)};
is $@ => '', 'Create array';
eval q{Readonly \my @roa2 => (1, 2, 3, 4); $roa2[2] = 3};
@@ -31,11 +37,17 @@ SKIP:
like $@ => $expected, 'Modify hash';
}
SKIP:
-{ skip 'Readonly $@% syntax is for perl 5.8 or later', 9 unless $] >= 5.008;
+{ skip 'Readonly $@% syntax is for perl 5.8 or later', 11
+ unless $] >= 5.008;
eval q{Readonly my $ros => 45};
is $@ => '', 'Create scalar';
eval q{Readonly my $ros2 => 45; $ros2 = 45};
like $@ => $expected, 'Modify scalar';
+ eval q{Readonly my $roaref => [1, 2, 3, 4]; $roaref->[2] = 3};
+ like $@ => $expected, 'Modify scalar array reference';
+ eval
+ q{Readonly my $rohref => { key1 => "value", key2 => "value2" }; $rohref->{key1} = "value"};
+ like $@ => $expected, 'Modify scalar hash reference';
eval q{Readonly my @roa => (1, 2, 3, 4)};
is $@ => '', 'Create array';
eval q{Readonly my @roa2 => (1, 2, 3, 4); $roa2[2] = 3};
diff --git a/t/reassign.t b/t/verbose_api/reassign.t
similarity index 95%
rename from t/reassign.t
rename to t/verbose_api/reassign.t
index 1e0fcea..be81981 100644
--- a/t/reassign.t
+++ b/t/verbose_api/reassign.t
@@ -1,4 +1,4 @@
-#!perl -I..
+#!perl -I../lib
# Readonly reassignment-prevention tests
use strict;
use Test::More tests => 22;
@@ -13,7 +13,7 @@ my $err = qr/^Attempt to reassign/;
# Reassign scalar
eval { Readonly::Scalar $s1 => "a second scalar value" };
-like $@ => $err, 'Readonly::Scalar reassign die';
+ok defined $@, 'Readonly::Scalar reassign die';
is $s1 => 'a scalar value', 'Readonly::Scalar reassign no effect';
# Reassign array
@@ -88,6 +88,6 @@ SKIP:
# Reassign real constants
eval q{Readonly::Scalar "hello" => "goodbye"};
-like $@ => $err, 'Reassign real string';
+ok defined $@, 'Reassign real string';
eval q{Readonly::Scalar1 6 => 13};
-like $@ => $err, 'Reassign real number';
+ok defined $@, 'Reassign real number';
diff --git a/t/scalar.t b/t/verbose_api/scalar.t
similarity index 98%
rename from t/scalar.t
rename to t/verbose_api/scalar.t
index 547631f..fc29b15 100644
--- a/t/scalar.t
+++ b/t/verbose_api/scalar.t
@@ -1,4 +1,4 @@
-#!perl -I..
+#!perl -I../lib
# Readonly scalar tests
use strict;
use Test::More tests => 12;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libreadonly-perl.git
More information about the Pkg-perl-cvs-commits
mailing list