[kansaipm] Re: 猫集会のお願い
mishima at momo.so-net.ne.jp
mishima at momo.so-net.ne.jp
Sun Jul 16 12:55:42 CDT 2000
三嶋です。
From: Nagayoshi_Michio <cudjo at venus.dti.ne.jp>
Subject: [kansaipm] 猫集会のお願い
Date: Sun, 16 Jul 2000 11:35:21 +0900
> CUDJO@京都です。
>
> 昨日は早々に退散してしまい、申し訳ありませんでした m(_ _)m。
> 漏れ聞くところによると、例のカレンダーの曜日が狂うのは
> デバッグできたとのことですが、できれば完成版(?)を公開して
> くださいね。
昨日は(おっと、もうおとといか)お疲れ様でした。
たった1時間で、Perl/Tk の Hello, World! から年間カレンダーの
表示まで、無理なくステップアップしていく構成がすばらしかった
です。
曜日が狂うバグは、sub juldate の中でループを回して sub maxDay を
呼び出すところにありました。
for ( my $i = 1; $i < $month; $i++ ){
$ans += maxDay($year,$i); # ← $i が $month になってたの
}
直しましたので、完成版を添付しておきます。
> #「自作の別ソース内関数の呼び出し」は、おまじないが多すぎて
> #理解できていない (;_;)。
実は私も、わかっていたつもりでわかってないことがありました。
package 宣言がなければ、名前空間はメインと同じものが使われます。
そのため、MyDate 内で package 宣言をなくせば、パッケージ内の名前を
外に見せる(export)ためのおまじないも不要になります。
#package MyDate; # 変数名や関数名を、新しい名前空間に保持する。
#require Exporter; # 名前空間の外に変数名や関数名を見せるためのおまじない
#@ISA = qw(Exporter); # (同上)
#@EXPORT = qw(from_1_1_1 juldate leapYear weekday maxDay); # (同上)
↑ここらへんのおまじないは、まとめてコメントアウトしました。
> ともあれ、第2回猫集会も期待しています。よろしく。
-------------- next part --------------
#!/usr/local/bin/perl -w
use Tk;
use strict;
use FindBin;
use lib $FindBin::Bin;
use MyDate;
my $mw = new MainWindow;
my($y) = (localtime)[5]; # デフォルトは今月
$y += 1900; # localtime が返す年は「西暦−1900」なので注意
if( @ARGV == 1 ){ # 引数があれば、年をとる
($y) = @ARGV;
}
my $c = 0;
my $r = 0;
for my $m (1..12){
my $fr = $mw->Frame;
$fr->grid(-row=>$r, -column=>$c,
-sticky=>'n',
-padx=>10, -pady=>10);
if( ++$c >= 3 ){
$r ++;
$c = 0;
}
dispMonth($fr,$y,$m);
}
MainLoop;
##
## 月の表示
##
sub dispMonth {
my( $parent, $y, $m ) = @_;
my( $maxD ) = maxDay($y,$m);
my $r = 0; # 最初は0行目
my $c = weekday( $y, $m, 1 ); # 月曜が0列目として、1日の列から
my $color;
for ( my $d = 1; $d <= $maxD; $d++, $c++ ) {
if ( $c >= 7 ) { # 最後の列を超えるようなら
$r++; # 次の行へ行って
$c = 0; # 最初の列に戻る
}
if( $c == 0 ){
$color = 'red';
}elsif( $c == 6 ){
$color = 'blue';
}else{
$color = 'black';
}
my $label = $parent->Label(-text=>$d,
-foreground=>$color);
$label->grid(-row => $r, -column => $c);
}
}
-------------- next part --------------
#package MyDate;
#require Exporter;
#@ISA = qw(Exporter);
#@EXPORT = qw(from_1_1_1 juldate leapYear weekday maxDay);
use strict;
use integer;
##
## 指定された年月日に対して、西暦1年1月1日から数えた日数を返す
##
sub from_1_1_1 {
my( $year, $month, $day ) = @_;
my $lastyear = $year - 1;
my $ans = 365 * $lastyear
+ $lastyear / 4
- $lastyear / 100
+ $lastyear / 400 # ここまでが昨年末までの日数
+ juldate($year, $month, $day); # 今年に入ってから今日までの日数
return $ans;
}
##
## 指定された年月日に対して、1月1日から数えた日数を返す
##
sub juldate {
my( $year, $month, $day ) = @_;
# 今月初めから今日までの日数
my $ans = $day;
# 先月末までの日数を加算
for ( my $i = 1; $i < $month; $i++ ){
$ans += maxDay($year,$i);
}
return $ans;
}
##
## 指定された年が閏年なら True を返す
##
sub leapYear {
my($year) = @_;
return( $year % 400 == 0 or
$year % 4 == 0 && $year % 100 != 0 );
}
##
## 指定された年月日の曜日を返す(日=0〜土=6)
##
sub weekday {
my( $y, $m, $d ) = @_;
my $jd = from_1_1_1( $y, $m, $d );
return ( $jd % 7 ); # 7で割った余りを返す
}
##
## 指定された年月の日数を返す
##
sub maxDay {
my($y,$m) = @_;
my @maxTbl = (0,
31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31);
my $ans = $maxTbl[$m];
if( $m == 2 and leapYear($y) ){
$ans ++;
}
return $ans;
}
1;
More information about the Kansai-pm
mailing list