Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: I'm stuck adding more named parameters to a subroutine since the new named parameters might have the same name as the current ones.

by choroba (Abbot)
on Mar 25, 2013 at 10:10 UTC ( #1025268=note: print w/ replies, xml ) Need Help??


in reply to I'm stuck adding more named parameters to a subroutine since the new named parameters might have the same name as the current ones.

Can you please provide an example of the table you are not able to print? I was able to run the following with favourable output:

table(1, { id => 't1', headings => [ qw/NAME STRENGTH COMMENT/], data => [ [qw/1 2 no/], [qw/2 3 yes/]], whead => [ [qw/10 20 another/], [qw/100 200 comment/]], } );

Also, sticking to DRY, I would abstract the attributes building:

sub build_attributes { my ($options, @valid) = @_; my @attributes; my %validH; undef @validH{ @valid }; while (my ($attr, $value) = each %$options) { push @attributes, qq($attr="$value") if exists $validH{$attr}; } return @attributes; }
and use that instead of repeated push all over the code:
sub list { my ($tab, $list, $opt) = @_; my @attributes = build_attributes($opt, qw/id class style/); my $format = join ' ', q(), @attributes;
(Notice also how the $format could be joined without a conditional.)
لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ


Comment on Re: I'm stuck adding more named parameters to a subroutine since the new named parameters might have the same name as the current ones.
Select or Download Code
Re^2: I'm stuck adding more named parameters to a subroutine since the new named parameters might have the same name as the current ones.
by Lady_Aleena (Deacon) on Mar 25, 2013 at 20:22 UTC

    choroba, I had been looking at all of the @attributes and thinking something should be done about them, however, I was not seeing how to put them all into another subroutine. I am now looking for a way to have the attributes returned in the same order as @valid. I know it is just a nitpicky thing, but when I look at the HTML source, I would like my attributes in the same order for all of the elements.

    Losing the conditional for $format is very nice since it speeds up rendering just a smidgen.

    Now for an example of where I have hit a wall.

    table(1, { id => 't1', headings => [qw/NAME STRENGTH COMMENT/], whead => [ [1, [2, { style => 'text-align: right' }], 'no'], [2, [3, { style => 'text-align: right' }], 'yes'], [10, [20, { style => 'text-align: right' }], 'another'], [100, [200, { style => 'text-align: right' }], 'comment'], ], headings => [['List to go with the whead' { colspan => 3 }]], data => [ ['list', { class => 'info', colspan => 3, list => [$list, { cl +ass => 'two_cols' }] }] ], });

    As you can see, there is a second headings which, as of now, would overwrite the first headings. Also, the data row would come before the whead rows when the table is displayed. I included more complexity, with the second cell in each row having a style added. In the data row, I included how a list would be added into a cell.

    So what I am trying to figure out is how to put an order to the row groups and have more than one of a type of row group.

    Have a cookie and a very nice day!
    Lady Aleena
      If you want multiple instances of the same type with ordering, you should use an array instead of a hash. What about something like
      table(1, { id => 1, rows => [ { type => 'headings', data => [qw/NAME STRENGTH COMMENT/], }, { type => 'whead', data => [ [1, [2, { style => 'text-align: right' }], + 'no'], [2, [3, { style => 'text-align: right' }], + 'yes'], [10, [20, { style => 'text-align: right' }], + 'another'], [100, [200, { style => 'text-align: right' }], + 'comment'], ], }, { type => 'headings', data => [['List to go with the whead' { colspan => 3 }] +], }, { type => 'data', data => [ [ 'list', { class => 'info', colspan => 3, list => [$list, { class => 'two_cols' }] } ] ] } ] } );
      لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

        choroba, I am very close to having what I want now. I just have to figure out how to get some conditionals nestled in the code somewhere. The new table subroutine is...

        sub table { my ($tab,$opt) = @_; my $attributes = get_attributes($opt,['id','class','style']); my $open = 'table'.$attributes; line($tab,qq(<$open>)); line($tab + 1,qq(<caption>$opt->{caption}</caption>)) if $opt->{capt +ion}; cols($tab + 1, $_) if $opt->{cols}; for my $rowgroup (@{$opt->{rows}) { my $type = $rowgroup->[0]; my @rows = @{$rowgroup->[1]; my $attributes = $rowgroup->[2]; for my $row (@rows) { if ($type eq 'header') { row($tab + 1, $type , $row); } else { row($tab + 1, $type , $_) for @$row; } } } line($tab,q(</table>)); }

        I used an array as you suggested, but used arrays in the array instead. Here are several tables using it now.

        # From ArmorClass.pm my $table_id = idify($table_name); table($tab,{ id => $table_id, class => 'player_character armor_class +', caption => $table_name, rows => [ ['header',['&nbsp;',map(ucfirst $_,qw(unarmored armored))]], ['whead',\@rows], ['header',[['Armor', { colspan => 3 }]]], # This & next have a c +ondition. ['data',[[['list', { class => "info", colspan => 3, list => ['u' +,$armor] }]]]] ] }); # From Psionics.pm my $table_id = idify($table_name); table($tab, { id => "$table_id", class => 'player_character psionic +s', caption => $table_name, rows => [ ['header',['&nbsp;','Amount']], ['whead',\@rows] ] }); # From RogueSkills.pm my $table_id = idify($table_name); table($tab, { id => "$table_id", class => 'player_character rogue_sk +ills', caption => $table_name, rows => [ ['header',['Skill','%']], ['whead',\@rows], ['header',[['Other', { colspan => 2 }]]], ['data',[[['list', { class => "info", list => ['u',$other_skills +] }]]]] ] }); # From SavingThrows.pm my $table_id = idify($table_name); table($tab, { id => "$table_id", class => 'player_character saving_ +throws', caption => $table_name, rows => [ ['header',['Save','Throw']], ['whead',\@rows], ['header',[['Modifiers', { colspan => 2}]]], # This & next have +a condition. ['data',[[['list', { class => "info", colspan => 2, list => ['u' +,$modifiers] }]]]] ] }); #From SpellProgression.pm my $table_id = idify($table_name); table($tab, { id => "$table_id", class => 'player_character spell +_progression', caption => $table_name, rows => [ ['header',\@headings], ['whead',\@rows], ['header',[['Spellbook', { colspan => $colspan }]]], # This & +next have a condition. ['data',[[[qq(<a href="../../../Role_playing/Spellbooks/$filen +ame.pl">$name\'s Spellbook</a>), { colspan => $colspan }]]]] ] }); # From THAC0.pm my $table_id = idify($table_name); table($tab, { id => "$table_id", class => 'player_character THAC0', rows => [ ['header',\@headings], ['whead',\@rows], ['header',[['Weapons', { colspan => $colspan }]]], # This & next + have a condition. ['data',[[['list', { class => 'info', colspan => $colspan, list +=> ['u',$weapons, { class => 'two' }] }]]]] ] });

        They may not be pretty, but they work almost as I want them to. Thank you for your array suggestion.

        Have a cookie and a very nice day!
        Lady Aleena
Re^2: I'm stuck adding more named parameters to a subroutine since the new named parameters might have the same name as the current ones.
by Lady_Aleena (Deacon) on Mar 25, 2013 at 22:29 UTC

    choroba, I added get_attributes (formerly build_attributes) to the module, and it is much better now. I hope you do not mind I made a few changes to suit my finickiness. I have not made any other changes yet, still figuring it out. Thank you very much for the nudge regarding the attributes!

    Update: The above code was altered to include the new get_attributes two posts (as of this writing) down. The original code was...

    Have a cookie and a very nice day!
    Lady Aleena
      You are creating an unnecessary copy. You can
      retrun \@attributes;
      as well, the reference will be different each time as you are using my inside the sub.
      لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

        I decided to take it one step further along. :)

        sub get_attributes { my ($options, $valid) = @_; my @attributes; for (@{$valid}) { my $value = $options->{$_}; push @attributes, qq($_="$value") if $options->{$_}; } return join(' ',('',@attributes)); }

        Instead of joining them later, I just joined them in the subroutine.

        Have a cookie and a very nice day!
        Lady Aleena

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1025268]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2014-11-21 03:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (104 votes), past polls