0

假设我有一个像这样的“make_members”方法。

sub make_members {  
    my ($number_members) = @_;
    my $rows = SomeDBIModule->select(); 
    my $count = @$rows;             
    for ( my $i = $count + 1; $i < $count + 1 + $number_members; $i++ ) {
          $rows->insert(
              name => "name".$i, 
              type => "A",
              created_at => time,                 
         );                    
   }                                                        
 } 

到目前为止,一切都很好。现在想象该方法可以将输入 a、b 和 c 的用户数量作为输入:

sub make_members {  
    my ($number_members, $n_members_type_a, $n_members_type_b, $n_members_type_c) = @_;
    #....

要写这篇文章,我首先想到的是制作 3 个循环。第一个

     for ( my $i = $count + 1; $i < $count + 1 + $n_members_type_a; $i++ ){
          $rows->insert(
              name => "name".$i, 
              type => "A",
      #....

$count + 1 和 $n_members_type_b 之间的第二个。$count + 1 和 $n_members_type_c 之间的第三个。

这看起来太长太可怕了。有没有更好的方法来写这个?

4

2 回答 2

2

“三个或更多,使用一个for”。

只需将其打包在另一个循环中

sub make_members {
  my %number_members_for_type;
  @number_members_for_type{qw/A B C/} = @_;
  my $rows = ...;
  while (my ($type, $num) = each %number_members_for_type) {
    for my $i ( @$rows + 1 .. @$rows + $num ) {
      $rows->insert(
        name => "name$i",
        type => $type,
        ...
      )
    }
  }
}

这假设它被称为 like make_members($n_type_a, $n_type_b, $n_type_c)

对参数使用散列可以很好地扩展。

如果散列作为参数传递,我们可以概括这一点。如果name属性必须是唯一的 ID,并且插入只能由这个函数完成,那么我们也可以优雅地管理它:

sub make_inserter {
  my ($rows) = @_;
  my $id_counter = @$rows;
  return sub {
    my %type2nums = @_;
    while (my ($type, $num) = each %type2nums) {
      for my $i ($id_counter + 1 .. $id_counter + $num) {
        $rows->insert(
          name => "name$i",
          type => $type,
          ...
        );
      }
      $id_counter += $num;
    }
  };
}

...

# Careful! Do not make an inserter for the same handle twice!
my $make_members = make_inserter(SomeDBIModule->select);
$make_members->(A => 2, B => 3);

如果键的顺序很重要,我们应该这样做,因为哈希键的顺序是未定义的:

  ... # as before
  return sub {
    while (my ($type, $num) = splice @_, 0, 2) {
      ... # as before
    }
  };
于 2013-08-27T07:09:27.230 回答
0

对一个方法重复许多类似的参数通常表明有可能进行一些简化。

因此,不要接受数字列表,而是接受类型作为参数:

sub make_members {  
    my ($number_members, $member_type) = @_;

然后:

$rows->insert(
              name => "name".$i, 
              type => $member_type,
              created_at => time,                 
         );

然后适当地考虑调用代码。例如创建 x 次“A”、y 次“B”、z 次“C”:

%numbers_of = ( "A" => 4, "B" => 5, "C" => 2 );
for my $type (keys %numbers_of) {
    make_members( $numbers_of{ $type }, $type );
}
于 2013-08-27T07:22:02.360 回答