我的perl代码中有2 sub
个,但它们完全相同。我很好奇SO会如何重构它们来制作一个sub
。
它们唯一真正的区别是正则表达式和通过预处理语句的查询。准备好的陈述也采用不同的参数。
思想?
sub showcaseViewsSubData {
my ($api_call, $stat_section, $idsite, $prev_date, $last_of_month, $params, $subtable) = @_;
return unless ($subtable);
my %sub_params = %{ clone ($params) };
$sub_params{'idSubtable'} = $subtable->{'idsubdatatable'};
# $data contains views for each primary showcase page
my $data = &fetchStatsData($api_call, \%sub_params);
foreach my $visit_group (@$data) {
# ignore product pages
next if ($visit_group->{'url'} && $visit_group->{'url'} =~ /\/products?\//);
# if ($visit_group->{'url'} && $visit_group->{'url'} =~ /inthenews|pressreleases|downloads/) {
if ($visit_group->{'idsubdatatable'}) {
&showcaseViewsSubData($api_call, $stat_section, $idsite, $prev_date, $last_of_month, $params, $visit_group);
next;
}
my $division_name;
if ($visit_group->{'url'}) {
my $showcase_id = $visit_group->{'url'};
$showcase_id =~ s/^.*?\/(\d+)\/.*$/$1/;
$division_by_showcase_id_sth->execute($showcase_id);
($division_name) = $division_by_showcase_id_sth->fetchrow_array();
} else {
$visit_group->{'orig_label'} = $visit_group->{'label'};
$visit_group->{'label'} =~ s/-/%/g;
$visit_group->{'label'} =~ s|^/||g;
$visit_group->{'label'} .= '%';
$division_sth->execute($visit_group->{'label'});
($division_name) = $division_sth->fetchrow_array();
}
if ($division_name) {
## no idea why this is nb_hits, and not nb_actions, like every other method
my @data_value = ( { 'nb_actions' => ($visit_group->{'nb_hits'} || $visit_group->{'nb_visits'}), 'label' => $division_name } );
&updateCompanyStats($idsite, 'showcase', $prev_date, \@data_value);
}
}
return 1;
}
和
sub researchViewsSubData {
my ($api_call, $stat_section, $idsite, $prev_date, $last_of_month, $params, $subtable) = @_;
return unless ($subtable);
my %sub_params = %{ clone ($params) };
$sub_params{'idSubtable'} = $subtable->{'idsubdatatable'};
# $data contains views for each primary showcase page
my $data = &fetchStatsData($api_call, \%sub_params);
if (ref $data ne 'ARRAY') {
carp "$api_call returned something not an array!";
return 0;
}
foreach my $visit_group (@$data) {
# if ($visit_group->{'url'} && $visit_group->{'url'} =~ /inthenews|pressreleases|downloads/) {
if ($visit_group->{'idsubdatatable'}) {
&researchViewsSubData($api_call, $stat_section, $idsite, $prev_date, $last_of_month, $params, $visit_group);
next;
}
my $division_name;
if ($visit_group->{'url'}) {
my $tag_id = $visit_group->{'url'};
$tag_id =~ s/^.*?\/(\d+)\/.*$/$1/;
next if ($tag_id !~ /^\d+$/);
$division_by_tag_id_sth->execute(int($tag_id), int($idsite));
($division_name) = $division_by_tag_id_sth->fetchrow_array();
} else {
carp Dumper($visit_group);
}
if ($division_name) {
## no idea why this is nb_hits, and not nb_actions, like every other method
my @data_value = ( { 'nb_actions' => ($visit_group->{'nb_hits'} || $visit_group->{'nb_visits'}), 'label' => $division_name } );
&updateCompanyStats($idsite, 'research', $prev_date, \@data_value);
}
}
return 1;
}
答案 0 :(得分:5)
正如Sinan所说,你应该从头开始设计一个新的类或模块(或一组)来处理你需要的功能。
以下是我根据您的代码制作的内容。这只是一个给你指路的大纲。
package MyCompanyStats;
sub process_stats {
my $params = shift;
my $data = fetchStatsData($params);
foreach my $visit_group (@$data) {
process_stats_group($visit_group);
}
}
sub process_stats_group {
my $group = shift;
if ($group->{'url'}) {
my $showcase_id = get_showcase_id($group);
save_by_showcase_id($showcase_id, $group);
} else {
my $group_label = get_group_label($group);
save_by_label($group_label, $group);
}
}
sub get_group_label {
my $group = shift;
my $label = $group->{'label'};
for ($label) {
s/-/%/g;
s|^/||g;
}
$label .= '%';
return $label;
}
sub get_showcase_id {
my $group = shift;
my $showcase_id = $visit_group->{'url'};
$showcase_id =~ s/^.*?\/(\d+)\/.*$/$1/;
return $showcase_id;
}
1;
答案 1 :(得分:3)
当你携带这个很多行李时,你需要一些物品是个好例子。除此之外,您可以将它们全部打包成一个“bag”哈希或使用命名对参数 - 至少它看起来会更好。
从代码中我不知道为什么要调用每个代码,所以我把一个笨重的东西放到了名为theDifference
的哈希中。
use Params::Util qw<_ARRAY _HASH>;
sub viewsSubData {
my %params = @_ % 2 ? %{ &_HASH } : @_;
# we delete because 1. we don't pass it, and we use it once.
return unless my $subtable = delete $params{subtable};
# If we only want a hashref to pass to fetchStatsData then
# stream params and the desired value in a hashref, and we're done.
# don't need the clone() call because listing out the hash takes care of that.
# $data contains views for each primary showcase page
my $data
= fetchStatsData(
$params{api_call}
, { %{ $params{params} }
, idSubtable => $subtable->{'idsubdatatable'}
}
);
# This was made standard--because the loop will fail with the derefence, anyway
if ( _ARRAY( $data )) {
# returning undef is for bad states is standard in Perl
carp( "$api_call returned something not an array!" ) and return;
}
my $is_showcase = $params{theDifference};
foreach my $visit_group (@$data) {
# ignore product pages
next if $is_showcase
and $visit_group->{'url'}
and $visit_group->{'url'} =~ /\/products?\//
;
# if ($visit_group->{'url'} && $visit_group->{'url'} =~ /inthenews|pressreleases|downloads/) {
if ($visit_group->{'idsubdatatable'}) {
showcaseViewsSubData( %params, subtable => $visit_group);
next;
}
my $division_name;
if ( $visit_group->{'url'} ) {
my ( $tag_id ) = $visit_group->{'url'}=~ m{/(\d+)/};
$division_by_tag_id_sth->execute( $tag_id, ( $is_showcase ? () : int( $params{idsite} ));
($division_name) = $division_by_tag_id_sth->fetchrow_array();
}
elsif ( $is_showcase ) {
# orig_label seems to do nothing
for ( $visit_group->{label} ) {
s|^/||;
s/-/%/g;
}
$division_sth->execute( $visit_group->{'label'} . '%' );
($division_name) = $division_sth->fetchrow_array();
}
else {
carp Dumper( $visit_group ) . "\n ";
}
if ($division_name) {
## no idea why this is nb_hits, and not nb_actions, like every other method
my @data_value
= { nb_actions => ( $visit_group->{'nb_hits'} || $visit_group->{'nb_visits'} )
, label => $division_name
};
updateCompanyStats( $idsite, @params{ qw<theDifference prev_date> }, \@data_value );
}
}
return 1;
}
你会这样称呼它:
viewsSubData(
{ theDifference => $whatever ? 'showcase' : 'research'
, api_call => $api_call
, idsite => $idsite
, prev_date => $prev_date
, params => $params
, subtable => $subtable
# neither of these were used.
#, last_of_month => ??
#, stat_section => ??
});