srchulo
srchulo

Reputation: 5203

catalyst application-wide variable

I would like to be able to define an application-wide (global) variable in my Catalyst application so that I can access it in any controller I am in. The purpose for this is that I'm not repeating values around my app that for the most part never change. Currently I am defining variables in my_app.pm like so:

our $GLOBAL_VAR = 'value';

And then in my controllers, I try to access the variable just like I would a subroutine:

my_app::$GLOBAL_VAR

However, this does not work. Does anyone know the best way to do this, or a better way to achieve this in Catalyst? Thanks!

Upvotes: 2

Views: 894

Answers (3)

user1126070
user1126070

Reputation: 5069

To access such a global variable here is the right syntax:

say $my_app::GLOBAL_VAR;

Upvotes: 5

Jonathan Warden
Jonathan Warden

Reputation: 2502

I like to manage any sort of global state through a Catalyst plugin. Reasons:

  • A plugin allows you to get/set the data through an accessor method.
  • This avoids some of the safety issues of using $package::variables
  • This decouples code using the global state from the details of where it is stored.
  • Plugins make a convenient places to place other functionality that may be related to that global state.
  • Catalyst Plugins are surprisingly easy to implement.

Here's a sample implementation, building on RET's suggestion of using PACKAGE->config:

package YourApp::Catalyst::Plugin::MyGlobalState;

sub global_state {
  my $c = shift;
  if(@_) { # If passed an argument, set.
    $c->config->{global_state} = shift;
  }
  return $c->config->{global_state};
}

1;

Then in your main app:

package YourApp;

use Catalyst (
  ...
  '+YourApp::Catalyst::Plugin::GlobalState'
);

Then in a controller somewhere:

sub my_action {
  my $c = shift;

  my $global_state = $c->global_state;
  $c->global_state('new state');
}

Upvotes: 2

RET
RET

Reputation: 9188

I can see this has already been asked and answered, but there are other ways to achieve the aim of this question.

Personally, I like to put these things into the main program thus:

=== my_app.pm ===

__PACKAGE__->config->{GLOBAL_VAR} = 'value';


=== a nearby controller ===

if($c->config->{GLOBAL_VAR} eq 'value'){ 
    # etc
}

Be aware that neither method is immutable, and when you say "for the most part never change", you need to be really careful in a web-server environment where you have multiple persistent processes. Changing such values programmatically can affect subsequent requests processed by that child, and have no effect on the other children. Of course, you probably simply meant "the developer might change this parameter from time to time".

Hope that's useful to someone.

Upvotes: 5

Related Questions