我有一个基于驼鹿的类(Foo),它有4个属性,假设:
SF1...SF4每个类型都是HashRef[Any]。
目前,所有这些都有默认值。稍后,我们将从MySQL表中获取这些值。
我的方法是,让Foo类根据数据的来源使用角色,我可以将SF1...SF4存储在一个名为Foo::DB的角色中,它将为SF1...SF3提供来自数据库的默认值。
还有一个角色,Foo::Local,它将具有硬编码的默认值,所以稍后,当我们要使用DB时,我只需要更改“with...”。
我是在朝着正确的方向前进,还是应该以不同的方式去做呢?
发布于 2012-06-14 06:18:08
目前还不清楚为什么需要从角色中填充数据。我认为你可以只使用初始化器subs。让你的属性变得懒惰,然后定义init_attribute subs。第一次需要属性值时,如果尚未设置,则将调用初始化器sub来提供该值。当您插入数据库时,您可以简单地教您的初始化器如何查询数据库中的值。
package Foo;
has SF1 => ( is => 'rw', lazy => 1, isa => 'HashRef[Any]' );
sub init_SF1 {
{ hi => 'how are you' }
};或者,如果您希望能够来回切换(例如,为了测试),那么是的,您可以将初始化器捆绑到角色中,并根据情况应用角色。或者,您可以只在测试中提供内联的值。例如
use Test::More;
use Foo;
my $foo = Foo->new(
SF1 => {
row1 => 'fake test data',
row2 => 'also fake'
},
SF2 => {},
); # now init_SF[12] will not be called如果你告诉我你为什么要这么做,我就能给你一个更好的答案。
发布于 2013-01-12 05:17:02
让我看看我对你的理解是否正确。
您有四个属性,应该为它们指定默认值。
您已经在MySQL数据库模式中定义了该默认值。您希望发生的情况是,每当您创建一个Foo实例时,默认值都将由您在MySQL模式中定义的默认值填充。
如果我对你正在尝试做的事情的理解是正确的,那么我的建议是:不要那样做(除非这绝对是你项目的一个要求)。使用Moose的default或builder属性定义属性的默认值。
has 'bar' => (
default => 'fubar',
);如果您要查找已在数据库架构中设置的默认值,而不是在类中定义它们,您将为自己创建更多的工作,为程序增加不必要的复杂性,并将添加本可以避免的代价高昂的数据库调用。您需要解析数据库模式,并确定给定属性的默认值。您可能需要在每次创建新对象时执行此操作(开销很大),或者创建一个默认值的缓存。当然,您可以创建一个Moose扩展,它可以实现一些魔术,并透明地为您完成这项工作。对于一个不那么吸引人的解决方案,似乎有很多工作要做。我只会使用Moose的“default”属性,除非你有很好的理由不这样做。
https://stackoverflow.com/questions/8369007
复制相似问题