The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

CGI::Portable::Files - Manages virtual file system and app instance config files

DEPENDENCIES

Perl Version

        5.004

Standard Modules

        I<none>

Nonstandard Modules

        File::VirtualPath 1.0
        CGI::Portable::Errors 0.46 (a superclass)

SYNOPSIS

See CGI::Portable, which is a subclass of this.

DESCRIPTION

This class is designed to be inherited by CGI::Portable and implements some of that module's functionality; however, this class can also be used by itself. The split of functionality between several modules is intended to emphasize the fact that CGI::Portable is doing several tasks in parallel that are related but distinct, so you have more flexability to use what you need and not carry around what you don't use. Each module has the POD for all methods it implements.

This class implements two distinct but closely related "input" properties, the "file path", and the "preferences", which manage a virtual file system and application instance config data respectively. Please see VIRTUAL FILE SYSTEM OVERVIEW and INSTANCE PREFERENCES OVERVIEW below for a conceptual explanation of what these are for and how to use them.

This class also subclasses CGI::Portable::Errors, and so its "error list" property (output) and related methods are available for use through this class.

VIRTUAL FILE SYSTEM OVERVIEW

This class implements methods that manage a "file path" property, which is designed to facilitate easy portability of your application across multiple file systems or across different locations in the same file system. It maintains a "virtual file system" that you can use, within which your program core owns the root directory.

Your program core would take this virtual space and organize it how it sees fit for configuration and data files, including any use of subdirectories that is desired. This class will take care of mapping the virtual space onto the real one, in which your virtual root is actually a subdirectory and your path separators may or may not be UNIXy ones.

If this class is faithfully used to translate your file system operations, then you will stay safely within your project root directory at all times. Your core app will never have to know if the project is moved around since details of the actual file paths, including level delimiters, has been abstracted away. It will still be able to find its files. Only your program's thin instance startup shell needs to know the truth.

The file path property is a File::VirtualPath object so please see the POD for that class to learn about its features.

INSTANCE PREFERENCES OVERVIEW

This class implements methods that manage a "preferences" property, which is designed to facilitate easy access to your application instance settings. The "preferences" is a hierarchical data structure which has a hash as its root and can be arbitrarily complex from that point on. A hash is used so that any settings can be accessed by name; the hierarchical nature comes from any setting values that are references to non-scalar values, or resolve to such.

CGI::Portable::Files makes it easy for your preferences structure to scale across any number of storage files, helping with memory and speed efficiency. At certain points in your program flow, branches of the preferences will be followed until a node is reached that your program wants to be a hash. At that point, this node can be given back to this class and resolved into a hash one way or another. If it already is a hash ref then it is given back as is; otherwise it is taken as a filename for a Perl file which when evaluated with "do" returns a hash ref. This filename would be a relative path in the virtual file system and this class would resolve it properly.

Since the fact of hash-ref-vs-filename is abstracted from your program, this makes it easy for your data itself to determine how the structure is segmented. The decision-making begins with the root preferences node that your thin config shell gives to CGI::Portable at program start-up. What is resolved from that determines how any child nodes are gotten, and they determine their children. Since this class handles such details, it is much easier to make your program data-controlled rather than code-controlled. For instance, your startup shell may contain the entire preferences structure itself, meaning that you only need a single file to define a project instance. Or, your startup shell may just have a filename for where the preferences really are, making it minimalist. Depending how your preferences are segmented, only the needed parts actually get loaded, so we save resources.

SYNTAX

This class does not export any functions or methods, so you need to call them using object notation. This means using Class->function() for functions and $object->method() for methods. If you are inheriting this class for your own modules, then that often means something like $self->method().

CONSTRUCTOR FUNCTIONS AND METHODS AND CONTEXT SWITCHING

These functions and methods are involved in making new CGI::Portable::Files objects, except the last one which combines two existing ones. All five of them are present in both CGI::Portable and other classes designed to be inherited by it, including this one, because they implement its functionality.

new()

This function creates a new CGI::Portable::Files (or subclass) object and returns it.

initialize()

This method is used by new() to set the initial properties of objects that it creates.

clone([ CLONE ])

This method initializes a new object to have all of the same properties of the current object and returns it. This new object can be provided in the optional argument CLONE (if CLONE is an object of the same class as the current object); otherwise, a brand new object of the current class is used. Only object properties recognized by CGI::Portable::Files are set in the clone; other properties are not changed.

make_new_context([ CONTEXT ])

This method initializes a new object of the current class and returns it. This new object has some of the current object's properties, namely the "input" properties, but lacks others, namely the "output" properties; the latter are initialized to default values instead. As with clone(), the new object can be provided in the optional argument CONTEXT (if CONTEXT is an object of the same class); otherwise a brand new object is used. Only properties recognized by CGI::Portable::Files are set in this object; others are not touched.

take_context_output( CONTEXT[, LEAVE_SCALARS[, REPLACE_LISTS]] )

This method takes another CGI::Portable::Files (or subclass) object as its CONTEXT argument and copies some of its properties to this object, potentially overwriting any versions already in this object. If CONTEXT is not a valid CGI::Portable::Files (or subclass) object then this method returns without changing anything. The properties that get copied are the "output" properties that presumably need to work their way back to the user. In other words, this method copies everything that make_new_context() did not. This method will never copy any properties which are undefined scalars or empty lists, so a CONTEXT with no "output" properties set will not cause any changes. If any scalar output properties of CONTEXT are defined, they will overwrite any defined corresponding properties of this object by default; however, if the optional boolean argument LEAVE_SCALARS is true, then the scalar values are only copied if the ones in this object are not defined. If any list output properties of CONTEXT have elements, then they will be appended to any corresponding ones of this object by default, thereby preserving both (except with hash properties, where like hash keys will overwrite); however, if the optional boolean argument REPLACE_LISTS is true, then any existing list values are overwritten by any copied CONTEXT equivalents.

METHODS FOR THE VIRTUAL FILE SYSTEM

These methods are accessors for the "file path" property of this object, which is designed to facilitate easy portability of your application across multiple file systems or across different locations in the same file system. See the DESCRIPTION for more details.

get_file_path_ref()

This method returns a reference to the file path object which you can then manipulate directly with File::VirtualPath methods.

file_path_root([ VALUE ])

This method is an accessor for the "physical root" string property of the file path, which it returns. If VALUE is defined then this property is set to it. This property says where your project directory is actually located in the current physical file system, and is used in translations from the virtual to the physical space. The only part of your program that should set this method is your thin startup shell; the rest should be oblivious to it.

file_path_delimiter([ VALUE ])

This method is an accessor for the "physical delimiter" string property of the file path, which it returns. If VALUE is defined then this property is set to it. This property says what character is used to delimit directory path levels in your current physical file system, and is used in translations from the virtual to the physical space. The only part of your program that should set this method is your thin startup shell; the rest should be oblivious to it.

file_path([ VALUE ])

This method is an accessor to the "virtual path" array property of the file path, which it returns. If VALUE is defined then this property is set to it; it can be an array of path levels or a string representation in the virtual space. This method returns an array ref having the current virtual file path.

file_path_string([ TRAILER ])

This method returns a string representation of the file path in the virtual space. If the optional argument TRAILER is true, then a virtual file path delimiter, "/" by default, is appended to the end of the returned value.

This method updates the "virtual path" property of the file path by taking the current one and applying CHANGE_VECTOR to it using the FVP's chdir() method. This method returns an array ref having the changed virtual file path.

virtual_filename( CHANGE_VECTOR[, WANT_TRAILER] )

This method uses CHANGE_VECTOR to derive a new path in the virtual file-system relative to the current one and returns it as a string. If WANT_TRAILER is true then the string has a path delimiter appended; otherwise, there is none.

physical_filename( CHANGE_VECTOR[, WANT_TRAILER] )

This method uses CHANGE_VECTOR to derive a new path in the real file-system relative to the current one and returns it as a string. If WANT_TRAILER is true then the string has a path delimiter appended; otherwise, there is none.

add_virtual_filename_error( UNIQUE_PART, FILENAME[, REASON] )

This message constructs a new error message using its arguments and appends it to the error list. You can call this after doing a file operation that failed where UNIQUE_PART is a sentence fragment like "open" or "read from" and FILENAME is the relative portion of the file name. The new message looks like "can't [UNIQUE_PART] file '[FILEPATH]': $!" where FILEPATH is defined as the return value of "virtual_filename( FILENAME )". If the optional argument REASON is defined then its value is used in place of $!, so you can use this method for errors relating to a file where $! wouldn't have an appropriate value.

add_physical_filename_error( UNIQUE_PART, FILENAME[, REASON] )

This message constructs a new error message using its arguments and appends it to the error list. You can call this after doing a file operation that failed where UNIQUE_PART is a sentence fragment like "open" or "read from" and FILENAME is the relative portion of the file name. The new message looks like "can't [UNIQUE_PART] file '[FILEPATH]': $!" where FILEPATH is defined as the return value of "physical_filename( FILENAME )". If the optional argument REASON is defined then its value is used in place of $!, so you can use this method for errors relating to a file where $! wouldn't have an appropriate value.

METHODS FOR INSTANCE PREFERENCES

These methods are accessors for the "preferences" property of this object, which is designed to facilitate easy access to your application instance settings. See the DESCRIPTION for more details.

resolve_prefs_node_to_hash( RAW_NODE )

This method takes a raw preferences node, RAW_NODE, and resolves it into a hash ref, which it returns. If RAW_NODE is a hash ref then this method performs a single-level copy of it and returns a new hash ref. Otherwise, this method takes the argument as a filename and tries to execute it. If the file fails to execute for some reason or it doesn't return a hash ref, then this method adds a file error message and returns an empty hash ref. The file is executed with "do [FILEPATH]" where FILEPATH is defined as the return value of "physical_filename( FILENAME )". The error message uses a virtual path.

resolve_prefs_node_to_array( RAW_NODE )

This method takes a raw preferences node, RAW_NODE, and resolves it into an array ref, which it returns. If RAW_NODE is a hash ref then this method performs a single-level copy of it and returns a new array ref. Otherwise, this method takes the argument as a filename and tries to execute it. If the file fails to execute for some reason or it doesn't return an array ref, then this method adds a file error message and returns an empty array ref. The file is executed with "do [FILEPATH]" where FILEPATH is defined as the return value of "physical_filename( FILENAME )". The error message uses a virtual path.

get_prefs_ref()

This method returns a reference to the internally stored "preferences" hash.

set_prefs( VALUE )

This method sets this object's preferences property with the return value of "resolve_prefs_node_to_hash( VALUE )", even if VALUE is not defined.

pref( KEY[, VALUE] )

This method is an accessor to individual settings in this object's preferences property, and returns the setting value whose name is defined in the scalar argument KEY. If the optional scalar argument VALUE is defined then it becomes the value for this setting. All values are set or fetched with a scalar copy.

AUTHOR

Copyright (c) 1999-2001, Darren R. Duncan. All rights reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. However, I do request that this copyright information remain attached to the file. If you modify this module and redistribute a changed version then please attach a note listing the modifications.

I am always interested in knowing how my work helps others, so if you put this module to use in any of your own code then please send me the URL. Also, if you make modifications to the module because it doesn't work the way you need, please send me a copy so that I can roll desirable changes into the main release.

Address comments, suggestions, and bug reports to perl@DarrenDuncan.net.

SEE ALSO

perl(1), File::VirtualPath, CGI::Portable::Errors, CGI::Portable.