如何捕获成员变量的访问权限?
$Class1->{Class2}
如果Class2
字段不存在,是否可以从内部函数中捕获它?
答案 0 :(得分:1)
你可以,但你可能不应该。这里的问题是 - 如果你直接访问类中的变量...那么你就可以。你可以通过几种解决方法来防止这种情况 - 这就是Moose之类的东西。
还有一些像内而外的对象(我认为不再是常见的做法) - 或Perl Best Practice在几年前提倡它们或者使用匿名哈希来保持状态。
但失败了 - 为什么不使用访问器,并使用' AUTOLOAD'自动生成一个访问器。
#!/usr/bin/env perl
package MyClass;
use strict;
use warnings;
use vars '$AUTOLOAD';
sub AUTOLOAD {
my ( $self ) = @_;
my $subname = $AUTOLOAD =~ s/.*:://r;
if ( $self -> {$subname} ) {
return $self -> {$subname};
}
warn "Sub called $subname was called\n";
return "$subname";
}
sub new {
my ( $class ) = @_;
my $self = {};
bless $self, $class;
}
package main;
use strict;
use warnings;
my $object = MyClass -> new;
$object -> {var} = "fleeg";
print "Undef fiddle was: ", $object -> fiddle,"\n";
print "But 'var' was: ", $object -> var,"\n";
这有同样的问题,因为更改方法名称可能会导致事情中断。但它的优点是你可以处理无效的'方法调用,但你喜欢。
但真的 - 明确'得到'和'设置'对于大多数用例来说,方法是更好的选择。
答案 1 :(得分:0)
您可以通过提供包含类/实例变量的正确getter / setter方法来实现此目的。永远不应该直接访问内部,特别是从类本身外部访问(除了保持特定属性的实际方法之外,在类中也不这样做是明智的。这是一个非常基本的例子:
use warnings;
use strict;
package A;
sub new {
my ($class, %args) = @_;
my $self = bless {}, $class;
$self->x($args{x});
$self->y($args{y});
return $self;
}
sub x {
my ($self, $x) = @_;
$self->{x} = $x if defined $x;
return $self->{x} // 1;
}
sub y {
my ($self, $y) = @_;
$self->{y} = $y if defined $y;
return $self->{y} // 2;
}
package main;
my $obj = A->new(x => 5, y => 3);
print $obj->x ."\n";
print $obj->y ."\n";
现在,您可以轻松地执行print $obj->{x}
,但这就是您的问题所在。当代码比这复杂得多时会发生什么,并且出于某种原因,您希望将x
属性名称更改为foo
,但保留x()
方法? $obj->{x}
现在将undef
为未设置。
始终使用提供的方法来访问类/对象的属性。像这样的封装是面向对象编程的主要内容。