催化剂应用范围的变量

时间:2013-03-05 07:31:50

标签: perl global-variables catalyst

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

our $GLOBAL_VAR = 'value';

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

my_app::$GLOBAL_VAR

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

3 个答案:

答案 0 :(得分:5)

我可以看到已经有人问过并回答过,但还有其他方法可以达到这个问题的目的。

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

=== my_app.pm ===

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


=== a nearby controller ===

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

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

希望这对某人有用。

答案 1 :(得分:4)

要访问这样的全局变量,请使用正确的语法:

say $my_app::GLOBAL_VAR;

答案 2 :(得分:2)

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

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

这是一个示例实现,基于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');
}