2

我希望能够在我的Catalyst应用程序中定义一个应用程序范围的(全局)变量,以便我可以在我所在的任何控制器中访问它。这样做的目的是我不会在我的应用程序周围重复用于大部分永远不会改变。目前我正在my_app.pm像这样定义变量:

our $GLOBAL_VAR = 'value';

然后在我的控制器中,我尝试像访问子程序一样访问变量:

my_app::$GLOBAL_VAR

但是,这不起作用。有谁知道做到这一点的最佳方法,或者在 Catalyst 中实现这一目标的更好方法?谢谢!

4

3 回答 3

5

在这里访问这样的全局变量是正确的语法:

say $my_app::GLOBAL_VAR;
于 2013-03-05T07:59:40.977 回答
5

我可以看到已经提出并回答了这个问题,但是还有其他方法可以实现这个问题的目的。

就个人而言,我喜欢将这些东西放入主程序中:

=== my_app.pm ===

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


=== a nearby controller ===

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

请注意,这两种方法都不是一成不变的,当您说“大多数情况下永远不会改变”时,您需要在拥有多个持久进程的 Web 服务器环境中非常小心。以编程方式更改这些值会影响该子进程处理的后续请求,而不会影响其他子进程。当然,您可能只是说“开发人员可能会不时更改此参数”。

希望这对某人有用。

于 2013-03-07T01:39:24.310 回答
2

我喜欢通过 Catalyst 插件管理任何类型的全局状态。原因:

  • 插件允许您通过访问器方法获取/设置数据。
  • 这避免了使用 $package::variables 的一些安全问题
  • 这将使用全局状态的代码与其存储位置的详细信息分离。
  • 插件为放置可能与该全局状态相关的其他功能提供了方便的位置。
  • Catalyst 插件非常容易实现。

这是一个示例实现,基于 RET 使用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;

然后在您的主应用程序中:

package YourApp;

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

然后在某处的控制器中:

sub my_action {
  my $c = shift;

  my $global_state = $c->global_state;
  $c->global_state('new state');
}
于 2016-11-12T18:34:22.523 回答