Perl 和契约式设计

Posted

技术标签:

【中文标题】Perl 和契约式设计【英文标题】:Perl and design by contract 【发布时间】:2020-11-11 10:56:03 【问题描述】:

我知道 Perl 有 perldoc 用于类似于 Javadoc 等的文档目的。 但我想知道如何在 Perl 中记录一个特定的方法,即输入参数和输出参数的精确约定? 例如。输入应该是例如一个数组而不是一个标量等而不实际读取整个代码?

有可能吗?

【问题讨论】:

“输入应该是一个数组”是什么意思? sub foo (@) ? @choroba:该语法不是必须遵循的,对吧?所以我想如果是的话,它会作为文档吗? 您在寻找perlpod吗? @GMB:我理解 perlpod 的方式更多是记录方法的功能。输入/输出没有那么多。我错过了重点吗? @Jim:POD 为您提供了一种记录 Perl 代码的方法,以便之后可以轻松访问,而无需实际阅读源代码。作为 Perl 代码的作者,您在文档中添加的什么是您的决定... 【参考方案1】:

如果您浏览一些 CPAN 模块,您会看到几种方法,但最常见的是类似

=heading1 FUNCTIONS

=over 4

=item my $hash_ref = foo( @bars )

Returns the hashed bars fooed.

即每个函数在=item 中显示其用法。

有些作者倾向于从用例的角度编写文档,而不是列出功能。正如我们在 Perl 中所说的,TIMTOWTWTD(编写文档的方法不止一种)。

【讨论】:

【参考方案2】:

我越来越多地在文档中看到的一种模式是使用类似 Moose 的类型约束来记录方法或函数的参数和返回值。 Data::Maker 就是一个例子。

=item B<record_count> (I<Num>)
 
The number of records desired
 
=item B<data_sources> (I<HashRef>)
 
Used internally by Data::Maker.  It's a hashref to store open file handles.

这种东西可以与 Function::Parameters 或 Type::Params 之类的库配对,以实际检查传递给函数的参数。

使用 Function::Parameters + Types::Standard:

=item C<< add($x, $y) >> : B<Num>, B<Num> -> B<Num>

Adds two numbers and returns the result.

=cut

fun add ( Num $x, Num $y ) 
   return Num->( $x + $y );

或者使用 Type::Params + Types::Standard:

=item C<< add($x, $y) >> : B<Num>, B<Num> -> B<Num>

Adds two numbers and returns the result.

=cut

sub add 
   state $check = compile( Num, Num );
   my ( $x, $y ) = &$check;
   return Num->( $x + $y );

【讨论】:

以上是关于Perl 和契约式设计的主要内容,如果未能解决你的问题,请参考以下文章

6.3 契约式设计

从零开始写一个契约测试工具——数据库设计

契约测试Pact

UML和模式应用5:细化阶段---操作契约

PHP 面向对象程序设计(oop)学习笔记 - 抽象类对象接口instanceof 和契约式编程

小酌重构系列[16]——引入契约式设计