short form for (defined $x and defined $y and ... )?

Discussion in 'Perl Misc' started by Markus Dehmann, Mar 25, 2006.

  1. I often find myself typing

    > unless(defined $x and defined $y and defined $z){ # ... many variables
    > # ...
    > }


    Is there a shorter form to write that? (I mean apart from "&&" for "and").

    Unfortunately,
    > unless(defined ($x,$y,$z))

    does not work.

    Thanks!
    Markus
    Markus Dehmann, Mar 25, 2006
    #1
    1. Advertising

  2. Markus Dehmann

    Uri Guttman Guest

    >>>>> "MD" == Markus Dehmann <> writes:

    MD> I often find myself typing
    >> unless(defined $x and defined $y and defined $z){ # ... many variables
    >> # ...
    >> }


    then don't type that! i suspect a poor design that makes you check many
    variables for defined. i have never seen that in quality code.

    what that means is to solve the real problem (why are you doing that)
    rather than the 'how do i do this?' problem.

    post (a short complete program) that shows why you do all those defined
    calls.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Mar 25, 2006
    #2
    1. Advertising

  3. Markus Dehmann

    robic0 Guest

    On Sat, 25 Mar 2006 00:14:07 -0500, Markus Dehmann <> wrote:

    >I often find myself typing
    >
    > > unless(defined $x and defined $y and defined $z){ # ... many variables
    > > # ...
    > > }

    >
    >Is there a shorter form to write that? (I mean apart from "&&" for "and").
    >
    >Unfortunately,
    > > unless(defined ($x,$y,$z))

    >does not work.
    >
    >Thanks!
    >Markus


    Stop thinking of Perl in a English sentence(y) way.
    Even though the very "evil" word *unless* is available,
    logic is Boolean! In more understandable terms its called
    "Formal Symbolic Logic" and its offered as an elective at
    every JC in the country (for 3 credits... whoop!).

    Its a course without which, imo, you will run into problems
    with the if/then/else construct. Btw, that course takes you
    through the analysis of English sentences, then paragraphs,
    then documents, where you have to write symbolic logic
    expressions, turn English into logic, then for the grand
    finally, you have to solve the logic equations just written
    to give an overall TRUTH to the statement/paragraph/document.
    Oh and there are the FORMAL ERRORS you have to deliniate.
    20 or so. If you don't get an 'A' in this course there could
    be trouble with programming.

    "Shorter" is not better. Never was and never will be.
    Shorthand notation you see on the usenet group are willfull
    attempt to mislead. Deception is actually power here.

    There is *NO* hidden logic, manifested by notation or keywords,
    that make the code work faster or better beyond the fully
    exposed if/then/else construct.

    You actually have to "break the code down into simple logic"
    before it can be optimized. If it can't be optimized when
    expressed simply, then it *CANNOT* be optimized anyway else !!!

    Hope you understand that?

    robic0
    robic0, Mar 25, 2006
    #3
  4. Markus Dehmann

    Guest

    Markus Dehmann wrote:
    > I often find myself typing
    >
    > > unless(defined $x and defined $y and defined $z){ # ... many variables
    > > # ...
    > > }

    >
    > Is there a shorter form to write that? (I mean apart from "&&" for "and").
    >
    > Unfortunately,
    > > unless(defined ($x,$y,$z))

    > does not work.



    Perhaps you have a preference between these two:

    use List::MoreUtils qw/all/;

    # ...

    if (all { defined $_ } ($x, $y, $z))
    {
    print "Hello ";
    }

    # or

    if (3 == grep defined $_, ($x, $y, $z))
    {
    print "World\n";
    }

    --
    Hope this helps,
    Steven
    , Mar 25, 2006
    #4
  5. Markus Dehmann

    robic0 Guest

    On 24 Mar 2006 22:06:27 -0800, "" <> wrote:

    >Markus Dehmann wrote:
    >> I often find myself typing
    >>
    >> > unless(defined $x and defined $y and defined $z){ # ... many variables
    >> > # ...
    >> > }

    >>
    >> Is there a shorter form to write that? (I mean apart from "&&" for "and").
    >>
    >> Unfortunately,
    >> > unless(defined ($x,$y,$z))

    >> does not work.

    >
    >
    >Perhaps you have a preference between these two:
    >
    >use List::MoreUtils qw/all/;
    >
    ># ...
    >
    >if (all { defined $_ } ($x, $y, $z))
    >{
    > print "Hello ";
    >}
    >
    ># or
    >
    >if (3 == grep defined $_, ($x, $y, $z))
    >{
    > print "World\n";
    >}


    I've seen it all now, the whole thing. No need to wonder on
    my death bed. An actual reference to a module that does the
    && for you. Thats pretty close to "lets all just take drugs
    and get drunk". No need to program ever again.

    Hey! Wheres my goddammed Perl program that does my programming?
    Where'd I put that damned thing........ jeez!

    robic0
    robic0, Mar 25, 2006
    #5
  6. Uri Guttman wrote:
    >>>>>>"MD" == Markus Dehmann <> writes:

    >
    >
    > MD> I often find myself typing
    > >> unless(defined $x and defined $y and defined $z){ # ... many variables
    > >> # ...
    > >> }

    >
    > then don't type that! i suspect a poor design that makes you check many
    > variables for defined. i have never seen that in quality code.
    >
    > what that means is to solve the real problem (why are you doing that)
    > rather than the 'how do i do this?' problem.
    >
    > post (a short complete program) that shows why you do all those defined
    > calls.


    my ($x,$y,$z) = $userInput =~ m/(.+?)\s\+\s(.+?)\s=\s(.+)/;
    die("wrong input format") unless(defined $x and defined $y and defined $z);

    I write lots of little scripts like that match user input like this.
    Sure, it's not "quality code", but it's definitely not worth to spend
    more code on the user input error checking for my purposes. So, if I
    grep, say, 10 variables from the user input this (defined $x and defined
    ....) can be a little longish. I'd just like to say (defined ($x,$y,$z,...))

    Okay, but you're right, maybe I could change the design. Maybe something
    like this:

    if( $userInput =~ m/(.+?)\s\+\s(.+?)\s=\s(.+)/ ){
    ($x,$y,$z) = ($1,$2,$2);
    }
    else{
    die("wrong input format");
    }

    But again, this is longer, and I find my first version more intuitive.

    Markus
    Markus Dehmann, Mar 25, 2006
    #6
  7. Markus Dehmann <> wrote in
    news::

    > if( $userInput =~ m/(.+?)\s\+\s(.+?)\s=\s(.+)/ ){
    > ($x,$y,$z) = ($1,$2,$2);
    > }
    > else{
    > die("wrong input format");
    > }
    >
    > But again, this is longer, and I find my first version more intuitive.


    $userInput =~ m/(.+?)\s\+\s(.+?)\s=\s(.+)/ or die "...";
    my ($x, $y, $z) = ($1, $2, $3);

    Sinan
    --
    A. Sinan Unur <>
    (remove .invalid and reverse each component for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Mar 25, 2006
    #7
  8. Markus Dehmann

    Anno Siegel Guest

    <> wrote in comp.lang.perl.misc:
    > Markus Dehmann wrote:
    > > I often find myself typing
    > >
    > > > unless(defined $x and defined $y and defined $z){ # ... many variables
    > > > # ...
    > > > }

    > >
    > > Is there a shorter form to write that? (I mean apart from "&&" for "and").
    > >
    > > Unfortunately,
    > > > unless(defined ($x,$y,$z))

    > > does not work.


    [...]

    > if (3 == grep defined $_, ($x, $y, $z))
    > {
    > print "World\n";
    > }


    I'm not too happy with this solution. For one, it must be changed in
    two places when the set ($x, $y, $z) changes.

    if ( 0 == grep !defined, $x, $y, $z )

    is easier to maintain, but it suffers from double negation. Disguising one
    negation as "0 ==" helps a little.

    Like all grep's it runs through the whole list though the result is clear
    after the first undefined element is found. That is inefficient if lists
    are long and undefined elements are frequently present. List::Util has
    first() to offer, but in this particular case there is a snag. From the
    documentation:

    first BLOCK LIST
    Similar to "grep" in that it evaluates BLOCK setting $_ to each
    element of LIST in turn. "first" returns the first element where
    the result from BLOCK is a true value. If BLOCK never returns true
    or LIST was empty then "undef" is returned.

    Now, if we write

    first { !defined } $x, $y, $z;

    that will return an undefined value, if one is found (of course). It
    will also return an undefined value if none is found (BLOCK never returns
    true). That is unfortunate and makes first() unusable for this purpose.

    If the designer had decided to return empty in the exceptional case,

    sub first (&;@) {
    my $cond = shift;
    $cond->() and return $_ for @_;
    return;
    }

    one could say

    0 == (() = first { !defined } $x, $y, $z);

    This is somewhat cryptic, but it would be the way to go if efficiency
    was critical.

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Mar 25, 2006
    #8
  9. Markus Dehmann

    Guest

    Anno Siegel wrote:
    > <> wrote in comp.lang.perl.misc:
    >
    > [...]
    >
    >
    > > if (3 == grep defined $_, ($x, $y, $z))
    > > {
    > > print "World\n";
    > > }

    >
    > I'm not too happy with this solution. For one, it must be changed in
    > two places when the set ($x, $y, $z) changes.
    >
    > if ( 0 == grep !defined, $x, $y, $z )
    >
    > is easier to maintain, but it suffers from double negation. Disguising one
    > negation as "0 ==" helps a little.
    >
    > Like all grep's it runs through the whole list though the result is clear
    > after the first undefined element is found. That is inefficient if lists
    > are long and undefined elements are frequently present. List::Util has
    > first() to offer, but in this particular case there is a snag. From the
    > documentation:
    >
    > first BLOCK LIST
    > Similar to "grep" in that it evaluates BLOCK setting $_ to each
    > element of LIST in turn. "first" returns the first element where
    > the result from BLOCK is a true value. If BLOCK never returns true
    > or LIST was empty then "undef" is returned.
    >
    > [ ... ]




    Ah, makes perfect sense . I hadn't thought about the
    aspect of efficiency. Perhaps then I'd use the firstidx
    function from List::MoreUtils.

    Taking a peek at the XS source code for firstidx:

    http://search.cpan.org/src/VPARSEVAL/List-MoreUtils-0.19/MoreUtils.xs

    I see a "break" out of the "for" loop, so this need not evaluate
    more arguments than necessary:


    if ( (firstidx { !defined } ($x, $y, $z) ) < 0 )
    {
    # do something...
    }

    --
    Cheers,
    Steven
    , Mar 25, 2006
    #9
  10. Markus Dehmann

    Anno Siegel Guest

    <> wrote in comp.lang.perl.misc:
    > Anno Siegel wrote:
    > > <> wrote in

    > comp.lang.perl.misc:
    > >
    > > [...]
    > >
    > >
    > > > if (3 == grep defined $_, ($x, $y, $z))
    > > > {
    > > > print "World\n";
    > > > }

    > >
    > > I'm not too happy with this solution. For one, it must be changed in
    > > two places when the set ($x, $y, $z) changes.
    > >
    > > if ( 0 == grep !defined, $x, $y, $z )
    > >
    > > is easier to maintain, but it suffers from double negation. Disguising one
    > > negation as "0 ==" helps a little.
    > >
    > > Like all grep's it runs through the whole list though the result is clear
    > > after the first undefined element is found. That is inefficient if lists
    > > are long and undefined elements are frequently present. List::Util has
    > > first() to offer, but in this particular case there is a snag. From the
    > > documentation:
    > >
    > > first BLOCK LIST
    > > Similar to "grep" in that it evaluates BLOCK setting $_ to each
    > > element of LIST in turn. "first" returns the first element where
    > > the result from BLOCK is a true value. If BLOCK never returns true
    > > or LIST was empty then "undef" is returned.
    > >
    > > [ ... ]

    >
    >
    >
    > Ah, makes perfect sense . I hadn't thought about the
    > aspect of efficiency. Perhaps then I'd use the firstidx
    > function from List::MoreUtils.


    Oh, good. Must have missed that in List::MoreUtils.

    [...]

    > if ( (firstidx { !defined } ($x, $y, $z) ) < 0 )


    Aha. That's it then.

    Unlike Uri, occasionally I do want to verify that all members of a list
    (or an array) are defined. I found the behavior of List::Util::first
    less than satisfactory in that regard. Nice to know about firstidx.

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Mar 25, 2006
    #10
  11. Markus Dehmann

    Uri Guttman Guest

    >>>>> "MD" == Markus Dehmann <> writes:

    MD> my ($x,$y,$z) = $userInput =~ m/(.+?)\s\+\s(.+?)\s=\s(.+)/;
    MD> die("wrong input format") unless(defined $x and defined $y and defined $z);

    first rule, always check regexes for success before you use the
    values. other replies have shown how to do this.

    now let's look at that regex. all the grabs are .+'s which means they
    all have at least one char and nothing is optional so they all must grab
    something if the whole regex matches. that means you can't get an undef
    grabbed value if that regex matches. so your defined checks are
    redundant and can be removed provided you check the regex for
    success. so i was right about your checking defined on all of them.

    my ($x,$y,$z) = $userInput =~ m/(.+?)\s\+\s(.+?)\s=\s(.+)/ or
    die 'lousy input' ;

    look mommy! no calls to defined! :)

    MD> Okay, but you're right, maybe I could change the design. Maybe
    MD> something like this:

    MD> if( $userInput =~ m/(.+?)\s\+\s(.+?)\s=\s(.+)/ ){
    MD> ($x,$y,$z) = ($1,$2,$2);
    MD> }
    MD> else{
    MD> die("wrong input format");
    MD> }

    MD> But again, this is longer, and I find my first version more intuitive.

    or look at my version above. when you do something very simple based on
    a boolean, then condtional modifiers (trailing if/unless) or boolean ops
    (and, or ) are cleaner. they also save blocks which cost something to
    enter. and extra indents and {} waste pixels and those are a precious
    resource!

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Mar 25, 2006
    #11
  12. Markus Dehmann

    Uri Guttman Guest

    >>>>> "AS" == Anno Siegel <-berlin.de> writes:

    AS> Unlike Uri, occasionally I do want to verify that all members of a
    AS> list (or an array) are defined. I found the behavior of
    AS> List::Util::first less than satisfactory in that regard. Nice to
    AS> know about firstidx.

    i just design so that isn't needed. not too hard i think. there are many
    ways of doing things and i try to spend more time picking ones which
    don't make me code stuff like that (and other constructs i don't
    like. :)

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Mar 25, 2006
    #12
  13. Markus Dehmann

    Joe Smith Guest

    Markus Dehmann wrote:

    > my ($x,$y,$z) = $userInput =~ m/(.+?)\s\+\s(.+?)\s=\s(.+)/;
    > die("wrong input format") unless(defined $x and defined $y and defined $z);


    Others have shown you the proper way to do it, but I want to point out that
    die "wrong input format" unless defined $z;
    would handle it. If $z is defined, then there is no need to test $x or $y
    since they will be defined (even if they are null strings).
    -Joe
    Joe Smith, Mar 26, 2006
    #13
  14. Markus Dehmann

    Bart Lateur Guest

    Markus Dehmann wrote:

    >I often find myself typing
    >
    > > unless(defined $x and defined $y and defined $z){ # ... many variables
    > > # ...
    > > }

    >
    >Is there a shorter form to write that? (I mean apart from "&&" for "and").


    Invert the condition, and search for an undefined item.

    if(grep !defined, $x, $y, $z) { ... }

    --
    Bart.
    Bart Lateur, Mar 26, 2006
    #14
  15. Markus Dehmann

    Anno Siegel Guest

    Joe Smith <> wrote in comp.lang.perl.misc:
    > Markus Dehmann wrote:
    >
    > > my ($x,$y,$z) = $userInput =~ m/(.+?)\s\+\s(.+?)\s=\s(.+)/;
    > > die("wrong input format") unless(defined $x and defined $y and defined $z);

    >
    > Others have shown you the proper way to do it, but I want to point out that
    > die "wrong input format" unless defined $z;
    > would handle it. If $z is defined, then there is no need to test $x or $y
    > since they will be defined (even if they are null strings).


    They can't be "null" strings (the common term is "empty") because all
    captures have a "+" in it. Also, $z isn't special. If any one of the
    captures is set, all will.

    But using that test would require the reader to understand what the content
    of one match has to say about the content of the others. It is much clearer
    to test if the regex has matched at all and then just use the captures.

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Mar 26, 2006
    #15
  16. Markus Dehmann

    robic0 Guest

    On Sat, 25 Mar 2006 14:33:49 -0500, Uri Guttman <> wrote:

    >>>>>> "AS" == Anno Siegel <-berlin.de> writes:

    >
    > AS> Unlike Uri, occasionally I do want to verify that all members of a
    > AS> list (or an array) are defined. I found the behavior of
    > AS> List::Util::first less than satisfactory in that regard. Nice to
    > AS> know about firstidx.
    >
    >i just design so that isn't needed. not too hard i think. there are many
    >ways of doing things and i try to spend more time picking ones which
    >don't make me code stuff like that (and other constructs i don't
    >like. :)
    >
    >uri


    You insinuate a higher intelligence design while using code other folks program...
    Pretty soon you won't need to code at all.
    And I'm being quite literal. Knowledge of usage of other ppl's code is what your
    trying to master whithout knowing the methods.
    Doesn't it nagg your brain when people have to write code for you because your
    too lazy or stupid to do it yourself?

    robic0
    robic0, Mar 27, 2006
    #16
  17. Markus Dehmann

    robic0 Guest

    On Sat, 25 Mar 2006 14:28:34 -0500, Uri Guttman <> wrote:

    >>>>>> "MD" == Markus Dehmann <> writes:

    >
    > MD> my ($x,$y,$z) = $userInput =~ m/(.+?)\s\+\s(.+?)\s=\s(.+)/;
    > MD> die("wrong input format") unless(defined $x and defined $y and defined $z);
    >
    >first rule, always check regexes for success before you use the
    >values. other replies have shown how to do this.
    >

    Why advise sucess checking? One liners are encoraged here.

    >now let's look at that regex. all the grabs are .+'s which means they
    >all have at least one char and nothing is optional so they all must grab
    >something if the whole regex matches. that means you can't get an undef
    >grabbed value if that regex matches. so your defined checks are
    >redundant and can be removed provided you check the regex for
    >success. so i was right about your checking defined on all of them.


    Any regex, if successfull will have defined values, absent 'or's (|).
    Within or's (|), after sucessfull regex, its only necessary to check a
    single define within an 'or' block.
    Its essence is badly designed because of the 1 liners so much promoted
    in this group.

    >
    > my ($x,$y,$z) = $userInput =~ m/(.+?)\s\+\s(.+?)\s=\s(.+)/ or
    > die 'lousy input' ;
    >
    >look mommy! no calls to defined! :)
    >
    > MD> Okay, but you're right, maybe I could change the design. Maybe
    > MD> something like this:
    >
    > MD> if( $userInput =~ m/(.+?)\s\+\s(.+?)\s=\s(.+)/ ){
    > MD> ($x,$y,$z) = ($1,$2,$2);
    > MD> }
    > MD> else{
    > MD> die("wrong input format");
    > MD> }
    >
    > MD> But again, this is longer, and I find my first version more intuitive.
    >
    >or look at my version above. when you do something very simple based on
    >a boolean, then condtional modifiers (trailing if/unless) or boolean ops
    >(and, or ) are cleaner. they also save blocks which cost something to
    >enter. and extra indents and {} waste pixels and those are a precious
    >resource!
    >
    >uri

    Jeez, so you know 'cleaner' code. Care to explain what that means..

    robic0
    robic0, Mar 27, 2006
    #17
  18. Markus Dehmann

    robic0 Guest

    On Sun, 26 Mar 2006 01:18:36 -0800, Joe Smith <> wrote:

    >Markus Dehmann wrote:
    >
    >> my ($x,$y,$z) = $userInput =~ m/(.+?)\s\+\s(.+?)\s=\s(.+)/;
    >> die("wrong input format") unless(defined $x and defined $y and defined $z);

    >
    >Others have shown you the proper way to do it, but I want to point out that
    > die "wrong input format" unless defined $z;
    >would handle it. If $z is defined, then there is no need to test $x or $y
    >since they will be defined (even if they are null strings).
    > -Joe


    Well yes Joe, your right, and good point.
    robic0
    robic0, Mar 27, 2006
    #18
  19. Markus Dehmann

    robic0 Guest

    On 26 Mar 2006 13:28:21 GMT, -berlin.de (Anno Siegel) wrote:

    >Joe Smith <> wrote in comp.lang.perl.misc:
    >> Markus Dehmann wrote:
    >>
    >> > my ($x,$y,$z) = $userInput =~ m/(.+?)\s\+\s(.+?)\s=\s(.+)/;
    >> > die("wrong input format") unless(defined $x and defined $y and defined $z);

    >>
    >> Others have shown you the proper way to do it, but I want to point out that
    >> die "wrong input format" unless defined $z;
    >> would handle it. If $z is defined, then there is no need to test $x or $y
    >> since they will be defined (even if they are null strings).

    >
    >They can't be "null" strings (the common term is "empty") because all
    >captures have a "+" in it. Also, $z isn't special. If any one of the
    >captures is set, all will.
    >
    >But using that test would require the reader to understand what the content
    >of one match has to say about the content of the others. It is much clearer
    >to test if the regex has matched at all and then just use the captures.
    >
    >Anno


    But in abscence of '|' group, all matches are defined, allbeit empty $'vars.
    so his unless block will always be perfectly valid, on whole, given its design defficiencies.
    But for his purposes it does what he wants. There are no benchmark code inefficiencies to
    show in this example.

    Correct style, not intent.
    robic0, Mar 27, 2006
    #19
  20. Markus Dehmann

    Anno Siegel Guest

    <robic0> wrote in comp.lang.perl.misc:
    > On Sat, 25 Mar 2006 14:28:34 -0500, Uri Guttman <> wrote:
    >
    > >>>>>> "MD" == Markus Dehmann <> writes:


    [...]

    > Any regex, if successfull will have defined values, absent 'or's (|).


    Wrong.

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Mar 27, 2006
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Oodini
    Replies:
    1
    Views:
    1,749
    Keith Thompson
    Sep 27, 2005
  2. David Geering

    longs, long longs, short short long ints . . . huh?!

    David Geering, Jan 8, 2007, in forum: C Programming
    Replies:
    15
    Views:
    545
    Keith Thompson
    Jan 11, 2007
  3. Replies:
    4
    Views:
    798
    Kaz Kylheku
    Oct 17, 2006
  4. Ioannis Vranos

    unsigned short, short literals

    Ioannis Vranos, Mar 4, 2008, in forum: C Programming
    Replies:
    5
    Views:
    657
    Eric Sosman
    Mar 5, 2008
  5. Andre
    Replies:
    5
    Views:
    517
    Keith Thompson
    Jul 17, 2012
Loading...

Share This Page