Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
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 (Canon)
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 drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2015-07-04 23:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (60 votes), past polls