Don't use global variables. Global variables are a symptom of a wider problem: global state.

Instead of relying on modules/subs picking up data from some sort of global place, you should pass the data to the function as a parameter.

# this is bad... # sub do_something { if ( $MyApp::VERSION < 1.0 ) { # a global do_something_simple(); } else { do_something_complex(); } } do_something(); # this is good... # sub do_something { my ($version) = @_; if ( $version < 1.0 ) { # a local variable do_something_simple(); } else { do_something_complex(); } } do_something(1.2);

Eventually you may find yourself passing around quite a few bits of data like this (a version number, maybe a database handle too, and a filename for writing output):

use v5.14; use warnings; use DBI (); package MyApp { sub do_something { my ($version, $dbh, $output_file) = @_; if ( $version < 1.0 ) { # a local variable do_something_simple($output_file); } else { do_something_complex($output_file, $dbh); } } sub do_something_simple { my ($output_file) = @_; open my $fh, '>', $output_file or die; print $fh "Hello world\n"; } sub do_something_complex { my ($output_file, $dbh) = @_; open my $fh, '>', $output_file or die; print $fh "Hello world\n"; printf $fh "There are %d rows in the table.\n", $dbh->do("SELECT 1 FROM my_table"); } } MyApp::do_something( 1.2, DBI->connect("dbi:SQLite:dbname=myapp.sqlite"), '/tmp/output.txt', );

It can become cumbersome to pass them around from one function call to the next, and tricky to keep track of which functions need access to which data. That's where object-oriented programming becomes handy:

use v5.14; use warnings; use DBI (); package MyApp { use Class::Tiny qw( version dbh output_file ); sub do_something { my $self = shift; if ( $self->version < 1.0 ) { # an object attribute $self->do_something_simple; } else { $self->do_something_complex; } } sub do_something_simple { my $self = shift; open my $fh, '>', $self->output_file or die; print $fh "Hello world\n"; close $fh; } sub do_something_complex { my $self = shift; open my $fh, '>', $self->output_file or die; print $fh "Hello world\n"; printf $fh "There are %d rows in the table.\n", $self->dbh->do("SELECT 1 FROM my_table"); close $fh; } } my $app = MyApp->new( version => 1.2, dbh => DBI->connect("dbi:SQLite:dbname=myapp.sqlite"), output_file => '/tmp/output.txt', ); $app->do_something;
use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

In reply to Re: dynamiclly assigning values to global variables in modules by tobyink
in thread dynamiclly assigning values to global variables in modules by bazi

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.