In a message dated 3/22/2008 10:43:42 A.M. Eastern Standard Time,=20
fzarabozo@hotmail.com writes:
> Hello All,
>
> After reading a lot on the subject, I'=
m=20
guessing that it's not possible to
> do what I want to do, but anyway=
I=20
wanted to ask you about and hopefuly be
> wrong. :-)
>
>=
I=20
want to write a sub so I can use it like this:
>
>=20
--------------------------------
> mysub (a =3D> 1, b =3D> 2, c=20=
=3D> 3)=20
{
> # ...CODE...
> };
>=20
--------------------------------
>
> But, I haven't found any v=
alid=20
prototype combination to make that work.
> After reading the perlsub=20
documentation, at first I thought I would be able
> to do so like=20
this:
>
> --------------------------------
> sub mysyb=20
(\%&) {
> # ...CODE...
> }
>=20
--------------------------------
>
> But, of course, I was wron=
g.=20
Taking out the backslash is also wrong since
> the % will eat anythin=
g=20
after it.
>
>
> Please let me know if any of you know th=
e=20
way to correctly construct such
> prototype.
>
> Thanks=20=
in=20
advance.
>
>
> Cheers, :-)
>
> Paco
you are right that you cannot do what want to do with prototypes (unles=
s=20
you use perl 6),
because this is not what perl 5 prototypes are for.
however, you can do something similar (i.e., named,=20
defaulted parameters) as follows:
sub func {
my %args =3D (
param1 =3D> 1, #=20
parameter and its default value
param2 =3D> 2,
param3 =3D> 3,
defined $_[0] ? %{$_[0]} :=20
(), # passed parameters, if any
);
return $args{param1} * $args{param2} +=20
$args{param3};
}
my $x =3D func({ param3 =3D> 33, param1 =3D> 11, =
});
hth -- bill walters
style=3D"BACKGROUND-COLOR: transparent" face=3DArial color=3D#000000=20
size=3D2>_______________________________________________
ActivePerl mai=
ling=20
list
ActivePerl@listserv.ActiveState.com
To unsubscribe:=20
http://listserv.ActiveState.com/mailman/mysubs
V>
normal 10pt ARIAL, SAN-SERIF;">
Create a Home=20=
Theater Like the Pros.
eric-stromer?video=3D15?ncid=3Daolhom00030000000001" href=3D"http://home.aol=
..com/diy/home-improvement-eric-stromer?video=3D15?ncid=3Dao lhom0003000000000=
1" target=3D"_blank">Watch the video on AOL Home.
TML>
-------------------------------1206209517--
--===============0516929653==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
--===============0516929653==--
Re: Perl Prototypes
am 22.03.2008 19:51:05 von fzarabozo
Hi,
Thank you for your answer. I'm trying to use subs for a better looking HTML
and XML manipulation. I know there are several ways to pass parameters, but
as I said, I'm just trying to get a better looking code. For example, using
prototypes, I'm able to build an HTML table this way:
--------------------------
Table {
Tr {
Td {
# ...code or constant context...
};
Td {
# ...code or constant context...
};
};
Tr {
Td {
# ...code or constant context...
};
Td {
# ...code or constant context...
};
};
};
---------------------
That I already have done and working perfectly, and all HTML output is
generated correctly. However, I'd like to be able to do that specifying
optional properties for each tag. For example:
--------------------------
Table (border => 0, cellpadding => 4) {
Tr {
Td (width => 31) {
# ...code or constant context...
};
Td (valign => 'top') {
# ...code or constant context...
};
};
Tr {
Td {
# ...code or constant context...
};
Td (class => 'lastCell') {
# ...code or constant context...
};
};
};
---------------------
That would keep the great readable looking and would allow me to specify
important tag properties, specially for XML output.
I know there are plenty of modules that use somehow similar ways to
construct HTML or XML, even CGI.pm, but none of them has this clear syntax -
you have to pass all parameters like in your example.
Well, I was just exploring posibilities with prototypes, and since I got the
first example working great, I just wanted to know if there was a way to
acomplish the second example. According to perlsub, prototypes allow you to
create your own syntax to "copy" the way that builtin functions work. So,
this would be a "copy" of a "for ( ... ) { ... }" syntax, except that it
would not do a loop but other things.
Actually, using prototypes, I found the way to pass values after the first
block of code (e.g. table { ...code... } properties { ...code... };), kinda
the eval-catch example in perlsub, but that doesn't really keep the concept
of readability that I tried to get in the second example.
Thank you anyway for your answer. :-)
Cheers,
Paco Zarabozo
------------------------------------------------------------ ------------------------------
From: Foo JH
Sent: Saturday, March 22, 2008 11:25 AM
To: Zarabozo, Francisco (GE, Corporate)
Cc: Active State Perl Mailing List
Subject: Re: Perl Prototypes
If you're trying to write a sub with default params, you can try this:
sub mysub
{
my ($a,$b,$c) = @_;
$a ||= 1;
$b ||= 2;
$c ||= 3;
}
Zarabozo, Francisco (GE, Corporate) wrote:
> Hello All,
>
> After reading a lot on the subject, I'm guessing that it's not possible to
> do what I want to do, but anyway I wanted to ask you about and hopefuly be
> wrong. :-)
>
> I want to write a sub so I can use it like this:
>
> --------------------------------
> mysub (a => 1, b => 2, c => 3) {
> # ...CODE...
> };
> --------------------------------
>
> But, I haven't found any valid prototype combination to make that work.
> After reading the perlsub documentation, at first I thought I would be
> able
> to do so like this:
>
> --------------------------------
> sub mysyb (\%&) {
> # ...CODE...
> }
> --------------------------------
>
> But, of course, I was wrong. Taking out the backslash is also wrong since
> the % will eat anything after it.
>
>
> Please let me know if any of you know the way to correctly construct such
> prototype.
>
> Thanks in advance.
>
>
> Cheers, :-)
>
> Paco
>
>
>
> _______________________________________________
> ActivePerl mailing list
> ActivePerl@listserv.ActiveState.com
> To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
>
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
Re: Perl Prototypes
am 23.03.2008 01:53:05 von Mike Gillis
--Apple-Mail-1-293118892
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
delsp=yes;
format=flowed
On Mar 22, 2008, at 8:43 AM, Zarabozo, Francisco ((GE, Corporate))
wrote:
> I want to write a sub so I can use it like this:
>
> --------------------------------
> mysub (a => 1, b => 2, c => 3) {
> # ...CODE...
> };
> --------------------------------
Well, you can't do exactly that. The perl parser as it stands already
gets confused between what is supposed to be a value and what is
supposed to be interpreted, and I think handling the above case would
cause a massive amount of headaches for whoever was brave enough to
try adding support for it.
But you can, if you are adventurous (or crazy), try and do something
like that using a combination of attributes, prototyping, and source
filters. It's a Saturday, and I am either adventurous or crazy
depending on who you ask, so I gave it a shot. :)
It's not perfect, but perhaps it will give you a good place to start
from if you really want to delve into it.
Package, example script and output is attached.
Cheers,
Mike Gillis
--Apple-Mail-1-293118892
Content-Transfer-Encoding: 7bit
Content-Type: text/x-perl-script;
x-unix-mode=0744;
name=htmlAsPerl.pm
Content-Disposition: attachment;
filename=htmlAsPerl.pm
package htmlAsPerl;
# example of how to do crazy things with
# Filter::Simple, attributes, and the (&) prototype.
#
# use/copy/modify/distribute as you like.
#
use warnings;
use strict;
use base 'Exporter';
use Filter::Simple;
my @ELEMENTS = qw(
A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE
BODY BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV
DL DT EM FIELDSET FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML
I IFRAME IMG INPUT INS ISINDEX KBD LABEL LEGEND LI LINK MAP MENU META
NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P PARAM PRE Q S SAMP SCRIPT
SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD TEXTAREA
TFOOT TH THEAD TITLE TR TT U UL VAR
);
our @EXPORT = ("MODIFY_CODE_ATTRIBUTES", @ELEMENTS);
my $ELEMENT_RE = join '|', @ELEMENTS;
my $INDENT = 4; # spaces per nesting level
FILTER_ONLY
code => sub {
s/($ELEMENT_RE)\s*:/$1 sub :/g;
};
my %attr_cache;
my $spacedepth = 0;
sub MODIFY_CODE_ATTRIBUTES {
my ($pkg, $code, @attrs) = @_;
my @strings;
foreach (@attrs) {
/^([^(]+) (?: \( (.*) \) )?$/x;
push @strings, defined($2) ? "$1=$2" : $1;
}
my $attr_string = join ' ', @strings;
$attr_cache{$code} = $attr_string;
return ();
}
sub print_indented (@) {
my $spaces = " " x ($INDENT * $spacedepth);
print $spaces, @_;
}
sub element {
my ($name, $content) = @_;
my $attr_string;
if (defined($content)) {
$attr_string = delete $attr_cache{$content};
if (defined($attr_string)) {
print_indented "<$name $attr_string>\n";
}
else {
print_indented "<$name>\n";
}
$spacedepth++;
$content = &$content;
print_indented $content, "\n" if $content;
$spacedepth--;
print_indented "$name>\n";
}
else {
print_indented "<$name>$_$name>\n";
}
# return 0 to evaluate as false in 'if $content'
return 0;
}
# it would be really nice if we could do all of this
# automatically with @ELEMENTS, but it turns out that
# prototypes are a compile-time-only thing, so.......
sub A (;&) { element("A" , $_[0]); }
sub ABBR (;&) { element("ABBR" , $_[0]); }
sub ACRONYM (;&) { element("ACRONYM" , $_[0]); }
sub ADDRESS (;&) { element("ADDRESS" , $_[0]); }
sub APPLET (;&) { element("APPLET" , $_[0]); }
sub AREA (;&) { element("AREA" , $_[0]); }
sub B (;&) { element("B" , $_[0]); }
sub BASE (;&) { element("BASE" , $_[0]); }
sub BASEFONT (;&) { element("BASEFONT" , $_[0]); }
sub BDO (;&) { element("BDO" , $_[0]); }
sub BIG (;&) { element("BIG" , $_[0]); }
sub BLOCKQUOTE (;&) { element("BLOCKQUOTE", $_[0]); }
sub BODY (;&) { element("BODY" , $_[0]); }
sub BR (;&) { element("BR" , $_[0]); }
sub BUTTON (;&) { element("BUTTON" , $_[0]); }
sub CAPTION (;&) { element("CAPTION" , $_[0]); }
sub CENTER (;&) { element("CENTER" , $_[0]); }
sub CITE (;&) { element("CITE" , $_[0]); }
sub CODE (;&) { element("CODE" , $_[0]); }
sub COL (;&) { element("COL" , $_[0]); }
sub COLGROUP (;&) { element("COLGROUP" , $_[0]); }
sub DD (;&) { element("DD" , $_[0]); }
sub DEL (;&) { element("DEL" , $_[0]); }
sub DFN (;&) { element("DFN" , $_[0]); }
sub DIR (;&) { element("DIR" , $_[0]); }
sub DIV (;&) { element("DIV" , $_[0]); }
sub DL (;&) { element("DL" , $_[0]); }
sub DT (;&) { element("DT" , $_[0]); }
sub EM (;&) { element("EM" , $_[0]); }
sub FIELDSET (;&) { element("FIELDSET" , $_[0]); }
sub FONT (;&) { element("FONT" , $_[0]); }
sub FORM (;&) { element("FORM" , $_[0]); }
sub FRAME (;&) { element("FRAME" , $_[0]); }
sub FRAMESET (;&) { element("FRAMESET" , $_[0]); }
sub H1 (;&) { element("H1" , $_[0]); }
sub H2 (;&) { element("H2" , $_[0]); }
sub H3 (;&) { element("H3" , $_[0]); }
sub H4 (;&) { element("H4" , $_[0]); }
sub H5 (;&) { element("H5" , $_[0]); }
sub H6 (;&) { element("H6" , $_[0]); }
sub HEAD (;&) { element("HEAD" , $_[0]); }
sub HR (;&) { element("HR" , $_[0]); }
sub HTML (;&) { element("HTML" , $_[0]); }
sub I (;&) { element("I" , $_[0]); }
sub IFRAME (;&) { element("IFRAME" , $_[0]); }
sub IMG (;&) { element("IMG" , $_[0]); }
sub INPUT (;&) { element("INPUT" , $_[0]); }
sub INS (;&) { element("INS" , $_[0]); }
sub ISINDEX (;&) { element("ISINDEX" , $_[0]); }
sub KBD (;&) { element("KBD" , $_[0]); }
sub LABEL (;&) { element("LABEL" , $_[0]); }
sub LEGEND (;&) { element("LEGEND" , $_[0]); }
sub LI (;&) { element("LI" , $_[0]); }
sub LINK (;&) { element("LINK" , $_[0]); }
sub MAP (;&) { element("MAP" , $_[0]); }
sub MENU (;&) { element("MENU" , $_[0]); }
sub META (;&) { element("META" , $_[0]); }
sub NOFRAMES (;&) { element("NOFRAMES" , $_[0]); }
sub NOSCRIPT (;&) { element("NOSCRIPT" , $_[0]); }
sub OBJECT (;&) { element("OBJECT" , $_[0]); }
sub OL (;&) { element("OL" , $_[0]); }
sub OPTGROUP (;&) { element("OPTGROUP" , $_[0]); }
sub OPTION (;&) { element("OPTION" , $_[0]); }
sub P (;&) { element("P" , $_[0]); }
sub PARAM (;&) { element("PARAM" , $_[0]); }
sub PRE (;&) { element("PRE" , $_[0]); }
sub Q (;&) { element("Q" , $_[0]); }
sub S (;&) { element("S" , $_[0]); }
sub SAMP (;&) { element("SAMP" , $_[0]); }
sub SCRIPT (;&) { element("SCRIPT" , $_[0]); }
sub SELECT (;&) { element("SELECT" , $_[0]); }
sub SMALL (;&) { element("SMALL" , $_[0]); }
sub SPAN (;&) { element("SPAN" , $_[0]); }
sub STRIKE (;&) { element("STRIKE" , $_[0]); }
sub STRONG (;&) { element("STRONG" , $_[0]); }
sub STYLE (;&) { element("STYLE" , $_[0]); }
sub SUB (;&) { element("SUB" , $_[0]); }
sub SUP (;&) { element("SUP" , $_[0]); }
sub TABLE (;&) { element("TABLE" , $_[0]); }
sub TBODY (;&) { element("TBODY" , $_[0]); }
sub TD (;&) { element("TD" , $_[0]); }
sub TEXTAREA (;&) { element("TEXTAREA" , $_[0]); }
sub TFOOT (;&) { element("TFOOT" , $_[0]); }
sub TH (;&) { element("TH" , $_[0]); }
sub THEAD (;&) { element("THEAD" , $_[0]); }
sub TITLE (;&) { element("TITLE" , $_[0]); }
sub TR (;&) { element("TR" , $_[0]); }
sub TT (;&) { element("TT" , $_[0]); }
sub U (;&) { element("U" , $_[0]); }
sub UL (;&) { element("UL" , $_[0]); }
sub VAR (;&) { element("VAR" , $_[0]); }
1;
--Apple-Mail-1-293118892
Content-Transfer-Encoding: 7bit
Content-Type: text/x-perl-script;
x-unix-mode=0744;
name=example.pl
Content-Disposition: attachment;
filename=example.pl
#!/usr/bin/perl
# example usage for htmlAsPerl.pm
use strict;
use warnings;
use lib '.';
use htmlAsPerl;
P { "This is a paragraph." };
P : style("font-weight: bold") {
"This is a paragraph with attributes."
};
DIV { SPAN { EM foreach qw($_ is used if there's no code) } };
TABLE : border(0) : cellpadding(4) {
TR {
TD : width(31) {
"cell 1"
};
TD : valign("top") {
"cell 2"
};
};
TR {
TD {
join (' ', qw(executing code on), $^O);
};
TD : class("lastCell") {
"last cell"
};
};
}
--Apple-Mail-1-293118892
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
x-unix-mode=0644;
name=output
Content-Disposition: attachment;
filename=output
This is a paragraph.
This is a paragraph with attributes.
$_
is
used
if
there's
no
code
cell 1
|
cell 2
|
executing code on darwin
|
last cell
|
--Apple-Mail-1-293118892
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
--Apple-Mail-1-293118892--
Re: Perl Prototypes
am 23.03.2008 09:27:02 von fzarabozo
Thank you very much for your answer Mike. It's an interesting way to do it
and it gave me some new ideas. :-)
Have you seen phperl.pm? You can google for it. Now, that's being crazy. I
mean... why in heaven would anyone want to write Perl with the same
dirtyness as PHP? :-) It's anyway an interesting use to Filters too, though.
Thanks again.
Cheers,
Paco Zarabozo
From: Mike Gillis
Sent: Saturday, March 22, 2008 6:53 PM
To: Zarabozo, Francisco (GE, Corporate)
Cc: Active State Perl Mailing List
Subject: Re: Perl Prototypes
On Mar 22, 2008, at 8:43 AM, Zarabozo, Francisco ((GE, Corporate))
wrote:
> I want to write a sub so I can use it like this:
>
> --------------------------------
> mysub (a => 1, b => 2, c => 3) {
> # ...CODE...
> };
> --------------------------------
Well, you can't do exactly that. The perl parser as it stands already
gets confused between what is supposed to be a value and what is
supposed to be interpreted, and I think handling the above case would
cause a massive amount of headaches for whoever was brave enough to
try adding support for it.
But you can, if you are adventurous (or crazy), try and do something
like that using a combination of attributes, prototyping, and source
filters. It's a Saturday, and I am either adventurous or crazy
depending on who you ask, so I gave it a shot. :)
It's not perfect, but perhaps it will give you a good place to start
from if you really want to delve into it.
Package, example script and output is attached.
Cheers,
Mike Gillis
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
Re: Perl Prototypes
am 26.03.2008 16:35:48 von Ingo Schwarze
Hi Francisco,
of course you could just exchange the order of the two arguments:
Always put the scalar arguments (in this case, and in particular,
the CODE reference) first and the multi-component arguments (in
this case, the hash) last. But that's perhaps ugly for your purpose.
If you *really* want to pass a code reference after other arguments,
why don't you just make the other arguments references, too?
When passing multi-component arguments in the middle of an argument
list, using HASH or ARRAY references is of a robust, standard
solution, like so:
----- 8< ----- schnipp ----- >8 ----- 8< ----- schnapp ----- >8 -----
#!/usr/bin/perl
use warnings;
use strict;
sub apply_to_hash_values ($&) {
my ($attr, $func) = @_;
die "hash required" unless ref $attr eq 'HASH';
print "$_ => ", $func->($attr->{$_}), "\n" foreach keys %$attr;
}
sub sqr {
my $x = shift;
return $x ** 2;
}
print apply_to_hash_values { two => 2, three => 3 }, \&sqr;
----- 8< ----- schnipp ----- >8 ----- 8< ----- schnapp ----- >8 -----
But for your purpose, i doubt that's the right approach.
I see no point in using code references at all. Consider:
----- 8< ----- schnipp ----- >8 ----- 8< ----- schnapp ----- >8 -----
#!/usr/bin/perl
use warnings;
use strict;
sub T($;@) {
my $tag = shift || die 'tag required';
my $attr = ref $_[0] eq 'HASH' ? shift : {};
my $text = join '', @_;
return "<$tag" . (join '', (map " $_=\"$attr->{$_}\"", keys %$attr)) .
">$text$tag>\n";
}
print
T 'HTML', (
T 'HEAD', (
T 'TITLE', 'Greeting'
),
T 'BODY', (
T 'H1', { align => 'center' }, 'Hello World!'
),
);
----- 8< ----- schnipp ----- >8 ----- 8< ----- schnapp ----- >8 -----
Some of the other suggestions look more complicated than required.
Have fun,
Ingo
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs