【问题标题】:How to access the attributes of a class indirectly如何间接访问类的属性
【发布时间】:2020-08-10 11:43:01
【问题描述】:

这与我的另一个问题相似但不完全相同:Content checking some, not all, class attributes

我正在编写一个测试来验证处理对对象的影响。但是我不知道如何获取一组已知对象属性的值,而是使用相同的代码进行测试。类似于以下内容(不起作用):

class A { has $.a, has $.b, has $.c };
my A $v .=new(:1a, :2b);

for <a b> { ok $v.{$_} > 0 }; # this does not work, but illustrates the intent.

如果我使用哈希而不是对象,那么很容易从知道键的哈希中获取值。

目前我能想到的就是测试每个属性:

ok $v.a > 0;
ok $v.b > 0;

此外,我不想查看对象的所有属性,这是 .^attributes 给我的,只查看其中的一些。

【问题讨论】:

  • 你可以让你的不工作的例子很简单地工作:for &lt;a b&gt; { ok $v."$_"() &gt; 0 };。那能解决你的问题吗?您还可以实现 Associative 角色以使您的示例按原样工作。

标签: class attributes raku


【解决方案1】:

您遇到的问题——以及使用Hashes 比使用Classes 更容易进行此类测试的原因——是当您需要传递一个对象时,您传递的是StrHashes 不会出现此问题,因为(默认情况下)Hash 键已经字符串。

要记住的另一件重要事情是,从技术上讲,没有任何方法可以从对象外部直接访问 Raku 对象的属性 - Raku 没有公共属性,只是您可以从公共访问器方法访问的属性。这似乎是一种迂腐的区别,但在这里很重要:这意味着您需要一个可调用的 Method 对象(它比我在上一段中提到的“对象”更具体)。

正如 Tyil 在评论中提到的,您可以使用代码 for &lt;a b&gt; { ok $v."$_"() &gt; 0 }; 让 Raku 进入 dwym。这样做的原因是最终的() 强制Raku 将"$_" 的内插值视为Callable,在这种情况下意味着Method

不过,我希望稍微明确一点,并使用以下语法:

for $v.^methods.grep({.name ~~ 'a' | 'b'}) { ok $_($v) > 0}

(这利用了$object.methodmethod($object) 在语法上等价的事实。

请注意,我们有上面的grep,因为您只想测试A 的一些方法。然而,即使你想测试你添加到A 的所有方法,你可能仍然需要grep 来排除BUILDALL,这是由$v.^methods(:local) 返回的。我还没有弄清楚这是故意还是错误(它似乎不像本地方法)并且希望有人对此提出想法。

【讨论】:

  • .oO(想象一下你刚刚遇到了一个友好 Rakoons 的“对象!”协议。)“没有任何方法可以从对象外部直接访问 Raku 对象的属性”有一个这么说和说“不要注意幕后的那个人!”的智慧磅 (lb),但我 2 盎司 (oz) 中的第一个是 .^attributes。 “最后的 () 迫使 Raku 将 "$_" 的内插值视为 Callable”我的第二个问题是,这可以说是误导性的。可能没有这样的方法,就像普通的方法调用一样。相反,.^methods确实返回Callable对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 2014-06-11
  • 2019-07-14
  • 2013-06-12
  • 2021-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多