如何在 Perl 中保存一组对象?

发布于 2024-10-01 18:35:47 字数 393 浏览 3 评论 0原文

我想保留一组(驼鹿)对象,因此每个对象只能出现一次。

我考虑使用哈希,其中键是对象的地址,然后在添加对象之前检查键是否存在。这是常见做法吗?如何获取对象的地址?

更新

再想一想,简单地使用对象引用作为键有什么问题:

my %objects = ();

# some object (just created or or taken from somewhere...)
my $object ...

# add object to set
$objects{$object} = $object;

# operate on all objects
foreach my $obj (values %objects) {
...
}

I would like to keep a set of (Moose) objects, so each object could only appear once.

I thought of using a hash where the key is the address of the object then check for existence of the key before I add an object. Is that a common practice? How do I get the address of the object?

UPDATE

On second thought, what's wrong with simply using the object reference as the key:

my %objects = ();

# some object (just created or or taken from somewhere...)
my $object ...

# add object to set
$objects{$object} = $object;

# operate on all objects
foreach my $obj (values %objects) {
...
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

乖乖 2024-10-08 18:35:48

您可以使用 Set::Object

要获取引用的地址,可以使用 Scalar::Util::refaddr

You can use Set::Object.

To get the address of a reference, you can use Scalar::Util::refaddr.

猫瑾少女 2024-10-08 18:35:48

注意此答案仅适用于每个类保留一个对象 - 如果OP的意思是“一个唯一的对象实例,但每个类有多个实例”,则此答案是错误的,并且应该用司南的。

实现这种方法(称为单例)的常见模式是实现用于创建此类对象的工厂方法和用于保存它们的存储。

因此,您将拥有:

  • 包含工厂和对象集的包
  • 该包有一个散列,键是对象的类型(您可以使用类名作为类型),值是该类型的对象。
  • 工厂方法 make_object,作为参数之一提供对象的 type 来 make
  • 返回特定类型的对象的访问器(基本上是上面提到的哈希中的查找)
  • 可选地,“检索或创建”方法,其逻辑为 if (!exists_object($type)) { make_object($type);返回 get_object($type) }

NOTE This answer only applies if you want to keep one object per class - if the OP meant "one unique object instance but multiple instances per class", this answer is wrong and Sinan's should be used.

A common pattern to implement such an approach (called a Singleton), is to implement a factory method for creating such objects and a storage for keeping them.

So, you would have:

  • A package containing the factory and the object set
  • That package has a hash, with key being the type of object (you can use class name as a type) and the value being the object of that type.
  • A factory method make_object, which is provided as one of the arguments with the type of object to make
  • An accessor returning an object of a specific type (basically a lookup in the hash mentioned above)
  • Optionally, a "retrieve-or-create" method whith the logic of if (!exists_object($type)) { make_object($type); return get_object($type) }
孤独患者 2024-10-08 18:35:48

如果您有一个可以表示为标量的域密钥,则可以仅使用常规哈希。

A) 您拥有由 VIN-1、VIN-2 和 VIN-3 标识的汽车。这些可以是哈希的键。

B) 您有按类型识别的汽车,“轿车”、“SUV”、“皮卡”。但您可以拥有多辆不同的轿车。本质上,除了对象的唯一存在之外,没有域密钥。这不能用哈希来完成(除非正如您提到的,您尝试使用引用的地址,但不确定这种做法有多好)。

If you have a domain key that can be expressed as a scalar, you can just use a regular hash.

A) You have cars identified by VIN-1 and VIN-2 and VIN-3. Those can be keys to a hash.

B) You have cars identified by type, 'sedan', 'SUV', 'pick-up'. But you can have multiple, different sedans. Essentially, there is no domain key besides the unique existence of an object. This cannot be done with a hash (unless as you mentioned you try using the address of the reference, not sure how good of a practice that is though).

甜心小果奶 2024-10-08 18:35:48

我只需添加 MooseX::Singleton 到已经提到的单例解决方案列表。

I'd just add MooseX::Singleton to the list of singleton solutions already mentioned.

把回忆走一遍 2024-10-08 18:35:48

最简单的代码是:

our $SINGLETON;
sub new {
    return $SINGLETON if $SINGLETON;
    # .... normal object creation
    $SINGLETON = $self;
    return $self;
}

The simplest bit of code would be:

our $SINGLETON;
sub new {
    return $SINGLETON if $SINGLETON;
    # .... normal object creation
    $SINGLETON = $self;
    return $self;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文