quinta-feira, 3 de dezembro de 2009

Nice cloesure fun with perl... this is old (sep 25)

# use:
# my $date = date(startday, startmonth);
# print &$date;   # print and increase current date
# print &$date(1) # print but doesn't increase current date
#
# Behavior:
# every time that the $date is dereferenced,
# it increase the date in your inner code
# and return it, unless it called with a 
# bollean true argument; like 1. 

package Date;

sub chk {
    # return 1 if the item is found in list
    # arguments need be a reference or 
    # be passed as a refenrece
    my ($it, $lst) = @_; # (item, list)
    map  {
        return 1 if $_ == $$it;
    } @$lst;
    return 0;
}

sub date { 
    # $date = &date(startday, startmonth)
    # return a cloesure that return and 
    # increase the current date 
    # or not 
    my ($day, $mon) = (1,month(1)); # default;
       ($day, $mon) = ($_[0], month($_[1])) if @_; # get the 
                                                   # start 
                                                   # day/month
    return sub { 
        # &$date() or &$date(1);
 if ($day > lastday(&$mon(1))) {
            $day = 1; # lastday + 1 eq day first
            &$mon;    # increase the month
        }
        return ($day++, &$mon(1)) unless @_; # return in list
        return ($day,   &$mon(1));           # return but does't 
                                             # increase
    };
}

sub lastday { 
    # last(&$mon(1))
    # return the last properly day in current month
    my ($mon) = @_;     # take de current month
    return 28 if $mon == 2;    # february
    return 30 if chk(\$mon, [4,6,9,11]); # april.. november
    return 31;      # others
}

sub month { 
    # $mon = month(number)
    # return and increase the current month
    my $month = shift;
    return sub { 
        # &$month(1) or $month
        $month = 1 if $month == 13;
        return $month++ unless @_; # return it and increase
 return $month;             # return it and doesn't 
                                   # increase
    };
}

#little test
my $date = date();
for my $num (1 .. 365) {
    printf ("%2d/%2d\n", &$date);
}

cloesures are nice...

So.. here I have a function that return another funtion, i.e., a cloesure
to be brief.. cloesures closes code in its self
so I have a $date variable that is a reference(the pointer name in perl) to a function
and every time that I cancel this reference(like * does in C), the date (inside the variable) increase one day. I can have how much indepent dates I want. i.e
cloesure closes code... every date variable have a date value close inside of it

Nenhum comentário:

Postar um comentário