Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

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 (Priest)
on Mar 25, 2013 at 22:08 UTC ( [id://1025401]=note: print w/replies, xml ) Need Help??


in reply to 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.
in thread I'm stuck adding more named parameters to a subroutine since the new named parameters might have the same name as the current ones.

tobyink, headings are rows just like data and whead so modifying your example of usage ...

table(1, { id => 't1', rows => [ headings => [qw/NAME STRENGTH COMMENT/], whead => [ # multiple rows with the first cell being a header. [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, { class => 'two_cols' }] }]], ], });

I can understand why you would want to pass individual rows, however, you are not taking into consideration a table with hundreds or even thousands of rows. I have one table with over 2,000 rows, so I would prefer a way to pass them through with an arrayref. In my modified example, I put headings inside of rows. I can not have two headings currently and can not set the order in which the row groups are displayed.

Oh, line comes from another module, so if possible, is there a way to use it as is? I use line in every script I write where I am printing lines.

choroba suggested I build the @attributes separately, and I agree. I will be looking at what he did and see how I can modify it to my exact needs then adding it to the module.

Also, the last time I tried figuring out OO, I was told I did it all wrong. OO and I have not become friends yet. So, right now I do not know what to ask on how to change what you wrote to suit my desires. Give me a lot of time to understand what you wrote, please?

Update: It looks like you dropped the attributes from all the elements except table. Every HTML tag can have its own attributes. Since I am generating the HTML with perl, I could go really crazy and give every element its own id, but I will refrain.

Have a cookie and a very nice day!
Lady Aleena
  • Comment on 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.
  • Select or Download Code

Replies are listed 'Best First'.
Re^3: 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 tobyink (Canon) on Mar 26, 2013 at 09:39 UTC

    "Oh, line comes from another module, so if possible, is there a way to use it as is? I use line in every script I write where I am printing lines."

    Sure. I left it out in the interests of self-containedness. But it should just be a case of (in package MyElem):

    sub _line { shift; my $tab = shift; require The::Other::Module; The::Other::Module::line($tab, join " ", @_); }
    e

    "choroba suggested I build the @attributes separately, and I agree. I will be looking at what he did and see how I can modify it to my exact needs then adding it to the module."

    Yes, in my final update I did this.

    "Also, the last time I tried figuring out OO, I was told I did it all wrong."

    Yes, I recall. That's why I took it in stages, so you can see how one style of coding translates to another. If I'd just posted the final version, it might be a bit mysterious how the things in your code corresponds to mine.

    Seeing the different steps makes it clearer that I didn't really add or remove much; just structured it into smaller parcels; replaced arrayrefs and hashrefs with objects; and replaced function calls with method calls.

    The main thing this buys you is polymorphism: a table object can call the output method on one of the row objects it contains, and it doesn't need to care about what type of row it is.

    Polymorphism is the main reason why people bang on about about OO all the time. It's a really great way of maintaining separation of concerns (i.e, so the MyCell package knows all about how to output cells, but the MyRow package needs to know nothing about how to output cells), and providing extensibility. An example of extensibility might be that you could define a new cell class:

    { package MyCell::Important; use base "MyCell"; sub _init { my $self = shift; no warnings "uninitialized"; $self->{style} = "color:red;font-weight:bold;$self->{style}"; } }

    And you can use your MyCell::Important class in tables without needing to make any changes to the MyRow or MyTable classes at all!

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

      tobyink, you did a lot of appears to be great work but went way too fast. I now need to know how to pass data collected outside of the objects to pass to the objects, so let's get some external data.

      #!/usr/bin/perl use strict; use warnings FATAL => qw( all ); use CGI::Carp qw(fatalsToBrowser); use List::Util qw(sum min max); use URI::Encode qw(uri_encode); use lib 'files/lib'; use Base::HTML::Elements qw(table); # I would add this in, however, it is just too big. # print_menu was taken out for this example. # link_color applies color styles to links based on file extension. # I included link_color below. use Base::Menu qw(print_menu link_color); # Gets root data for my site. You can get rid of this. use Base::Roots qw(get_root); # Adds commas and rounds numbers. use Base::Number qw(pretty_number); use Base::Nifty qw(line); print "content-type: text/html \n\n"; # change this to the path of whatever directory you want. my $root_path = get_root('path'); my %extensions; my %file_sizes; my $file_sizes_sum; sub file_list { my $directory = shift; opendir(my $dir,$directory) or die "Can't open $directory $!"; my @temp = grep {/^\w/} readdir($dir); for (@temp) { if (-f "$directory/$_") { my $key = (split(/\./,$_))[-1]; ++$extensions{$key}; my $file_size = -s "$directory/$_"; my $file = "$directory/$_"; $file =~ s/$root_path\///; $file_sizes{$file}{bytes} = $file_size; $file_sizes{$file}{kilobytes} = $file_size/1024; $file_sizes{$file}{megabytes} = ($file_size/1024)/1024; $file_sizes_sum += $file_size; } if (-d "$directory/$_") { file_list("$directory/$_"); } } } file_list("$root_path"); my $extensions_sum = sum(values %extensions); my $extensions_types = keys %extensions; my $file_sizes_total = keys %file_sizes;

      Now, I have all kinds of wonderful data to pass to the table object, if only I know what was needed to get the other objects to work. So, let's start with %extensions and the cells which will go in the more than a dozen rows of the table; then we can go onto %file_sizes.

      my @ext_rows; for my $key (sort keys %extensions) { my $value = $extensions{$key}; my $color = link_color($key); # As you can see, the two cells in the rows each have $opt fields. # The first cell in the row gets a custom color for its text. # The second cell is part of a CSS class which is right aligned. push @ext_rows, [[$key, { style=> "$color" }],[$value, { class => 'r +ight' }]]; } # Here are the final two rows in the extensions table. Later they will + be plugged in # under whead. # The first cells in these two rows are headers which get no other spe +cial formatting. # The second cells in these two rows get right aligned with a CSS clas +s. my @ext_end_rows; push @ext_end_rows, ['Total files',[$extensions_sum, { class => 'right +' }]]; push @ext_end_rows, ['Total types',[$extensions_types, { class => 'rig +ht' }]]; # The table with file paths and file sizes is much much larger. # In the root directory I use, there are over 2,000 files meaning over + 2,000 rows. my @size_rows; for my $key (sort { $file_sizes{$b}{bytes} <=> $file_sizes{$a}{bytes} +|| $a cmp $b } keys %file_sizes) { my $bytes = $file_sizes{$key}{bytes}; my $kbytes = $file_sizes{$key}{kilobytes}; my $mbytes = $file_sizes{$key}{megabytes}; my $color = link_color($key); my $link = uri_encode($key); $key =~ s!&!&amp;!g; # Again, what do I store here? # The first cell is a link to the file. # The second through fourth are numbers which I mapped to be # pretty and be right aligned with a CSS class. push @size_rows, [qq(<a href="$link" style="$color">$key</a>), map { [pretty_number(5,$_), { class => 'right' }] } ($b +ytes,$kbytes,$mbytes) ]; } my $sum_bytes = $file_sizes_sum; my $sum_kbytes = $file_sizes_sum/1024; my $sum_mbytes = ($file_sizes_sum/1024)/1024; my $avg_bytes = $file_sizes_sum/$file_sizes_total; my $avg_kbytes = ($file_sizes_sum/$file_sizes_total)/1024; my $avg_mbytes = (($file_sizes_sum/$file_sizes_total)/1024)/1024; # Now these two rows are being stored with the other rows in the sizes + table # with the same formatting. push @size_rows, ['Totals',map { [pretty_number(5,$_), { class => 'rig +ht' }] } ($sum_bytes,$sum_kbytes,$sum_mbytes)]; push @size_rows, ['Averages',map { [pretty_number(5,$_), { class => 'r +ight' }] } ($avg_bytes,$avg_kbytes,$avg_mbytes)]; # With the way the data was gathered above, I was able to plug in the +data # into the tables in a one liner (though they wrapped here). I did not + store # the headings, since they did not require any real munging. table(3, { style => 'float:right', headings => ['Ext','Count'], data = +> [@ext_rows], whead => [@ext_end_rows] }); table(3, { headings => [qw(File bytes kilobytes megabytes)], whead => +[@size_rows] });

      So, what do I need to store in arrayrefs for each row for each cell in the row?

      link_color

      sub link_color { my ($file,$style) = @_; my $color = "000"; my %colors; $colors{pl} = "f00"; $colors{pm} = "900"; $colors{html} = "00f"; $colors{shtml} = "009"; $colors{svg} = "003"; $colors{css} = "060"; $colors{csv} = "0f0"; $colors{txt} = "090"; $colors{zip} = "990"; $colors{js} = "099"; $colors{pdf} = "c33"; $colors{wav} = "939"; $colors{xls} = "696"; $colors{doc} = "669"; $colors{pub} = "699"; $colors{$_} = "909" for (qw(gif ico jpg png bmp)); my ($extension,$name) = reverse split(/\./,$file); $color = $colors{$extension} ? $colors{$extension} : $color; return $style ? qq( style="color:#$color") : qq(color:#$color); }
      Have a cookie and a very nice day!
      Lady Aleena

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2024-04-25 12:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found