第112回 JavaのI/Oは Decoratorデザインパターン だったのか
引用:
私はDecoratorを知っていて読んだので問題ありませんでしたが、Decoratorを知らない読者は依然「どうしてこんなにオブジェクトをラップする必要があるのか」分からないのではないかと思います。
少し、Decoratorパターンについて調べてみた。
502 Bad Gateway
ギコ猫とDecoratorパターン
ん〜 どういう利点があるのかわからん。このパターン。
引用:
細かいクラスを乱造したのはアナタだ、と。
こうとしか捉えられない......
第111回 はてなブックマークの Web Hook試してみましたが
#!/usr/bin/perl use utf8; use strict; use warnings; use Data::Dumper; use CGI; my $req = CGI->new; open my $f, '>>log.txt'; print $f Dumper $req; close $f; print "Content-Type: text/plain\n\n";
ん〜〜
こない〜
日本語だと来ない気がする.......
と思って検索すると、
(開発者さま向け) はてなブックマーク Web Hook 機能を公開しました - はてなブックマーク日記 - 機能変更、お知らせなど
同じ症状の方がいらっしゃいました。
確かに、コメント(ブコメ)に日本語がはいっているとPOSTされていない気がする。
(始めはタグを含んでるとダメかと思ってが.... アルファベットで書いたタグはいけたし)
作るまで上記リンクのコメント欄読み飛ばしてしまっていた。
追記:改修されたようです。
第110回 クォートとパス名展開
*(アスタリスク)を囲うか? 囲わないか?
bashでコマンドを打つときに *(アスタリスク)を使う場面に出くわすことは多いと思います。
find / -name '*.txt'
とするとき、
「あれ? クォートいったけ? いらなかったけ?」
「この*(アスタリスク)はbashが展開する? findが展開する??
(たしか、クォートしなかった場合は、bashが展開したような....)」
となってしまいました。
この * をクォートで囲むべきなのか
はたまたダブルクォートで囲むべきなのか
いやいやクォートせずに使うべきなのか
曖昧な理解をやめるために調べてみました。
シングルクォートとダブルクォートの違いは?
http://www.linux.or.jp/JM/html/GNU_bash/man1/bash.1.html
こちらを参考に、以下引用を交えて調べていった結果を書きたいと思います。
(一部省略して引用しています)
引用:
クォートの方法には、 エスケープ文字(escape character), シングルクォート、ダブルクォート の 3 種類があります。
ダブルクォートで文字を囲むと クォート内部の全ての文字は文字としての値を保持しますが、 $, `, \ は例外となります。
なるほど
ダブルクォートは $, `, \が例外になるわけか。
ということは、*のみを使う場面ではシングルクォートを使っておくのがよいかもしれない。
パス名展開
引用:
展開はコマンドラインが単語へ分割された後に (コマンドライン上で) 行われます。 行われる展開は 7 種類あります: ブレースの展開 (brace expansion), チルダの展開 (tilde expansion), パラメータと変数の展開 (parameter and variable expansion), コマンド置換 (command substitution), 算術式展開 (arithmetic expansion), 単語の分割 (word splitting), パス名の展開 (pathname expansion)。
なるほどぉ
一口に展開といっても、7種類も展開があったのか、今回気になっているのは、
「パス名の展開」にあたるやつだ。
引用:
-f オプションが指定されていなければ、 単語分割を行った後に bash はそれぞれの単語が *, ?, [ を含んでいるかどうか調べます。 これらの文字のいずれかが見つかると、その単語は パターン と見なされ、 パターンにマッチするファイル名をアルファベット順にソートしたリストに置換されます。
なるほど
やはり、クォートしないとbashが展開しているのですね。
いま、以下のようなファイルがあるディレクトリで、echoを使ってみましょう。
$ ls f10 f11 f7 f8 f9
クォートなし
$ echo * f10 f11 f7 f8 f9
なるほど。展開されています。
クォートあり
$ echo '*' *
なるほど。展開されていません。
findに渡すとき
ではfindで試してみましょう。
クォートなし
$ find . -name f* find: f11: unknown option
これではfindに渡るまえにbashで展開されてしまい、f11なんていうオプションはないと怒られてしまいました。
クォートあり
$ find . -name 'f*' ./f10 ./f11 ./f7 ./f8 ./f9
うまくいきました。
findコマンドに'f*'という文字列として渡してあげて、その'f*'を、findコマンドによって解釈してもらわねばならないわけですね。
第109回 これは便利! ちょっとした技
bash
No.1 Ctr + a
[行頭移動]
NO.2 Ctr + k
[行末までバッファにコピー]
No.3 Ctr + y
[バッファの内容を貼り付け]
No.4 Ctr + a後 Ctr + k 作業後 Ctr +y
[途中まで打った内容を保存して別のコマンド実行]
何かコマンドを途中まで打っていて、
引数の順番を忘れた..... manをみたい......
でも....... 今、manを見るとまで打った内容がおじゃんだ....
そんな状況はないだろうか?
そんなときは
行頭に移動し、
行末までを切り取り(バッファーにコピーし)、
manを見た後で貼り付ければよい。
第108回 Oracleのお勉強 sqlplusのお勉強
sqlplusの表示は読みにくい。
それはなぜか? そこに迫ってみた。
linesize
SQL> show linesize linesize 10
こんな感じで、linsesize の値が小さいと
すごく改行される。
SQL> select * from user_role_privs; USERNAME ---------- GRANTED_RO ---------- ADMIN_ ------ DEFAUL ------ OS_GRA ------ SYS AQ_ADMINIS TRATOR_ROL 以下略
表示しているターミナルの横幅のバッファサイズ
こんな風に、横幅のバッファが小さいと、
その幅で改行される。
linesizeは80あるにも限らず、早めに改行されている
SQL> show linesize linesize 80 SQL> select * from u ser_role_privs; USERNAME -------------------- -------------------- -------------------- GRANTED_ROLE ADMIN_ DEFAUL -------------------- 以下略
第106回 Oracleのお勉強 GROUP BYを使って取得するものは一度に取得できないか考える
次の表で考えてみよう。
SQL> select * from ( 2 select sysdate 日付, 1 管理番号 from dual union 3 select sysdate 日付, 2 管理番号 from dual union 4 select sysdate 日付, 3 管理番号 from dual union 5 select sysdate+1 日付, 1 管理番号 from dual union 6 select sysdate+1 日付, 2 管理番号 from dual union 7 select sysdate+1 日付, 3 管理番号 from dual 8 ); 日付 管理番号 -------- ---------- 09-05-30 1 09-05-30 2 09-05-30 3 09-05-31 1 09-05-31 2 09-05-31 3 6行が選択されました。
日付ごとに最小管理番号、最大管理番号を求める
まず、効率の悪い例
最小を求める
SQL> select 2 to_char(t1.日付, 'YYYY/MM/DD') 日付, 3 min(t1.管理番号) 最小管理番号 4 from ( 5 select sysdate 日付, 1 管理番号 from dual union 6 select sysdate 日付, 2 管理番号 from dual union 7 select sysdate 日付, 3 管理番号 from dual union 8 select sysdate+1 日付, 1 管理番号 from dual union 9 select sysdate+1 日付, 2 管理番号 from dual union 10 select sysdate+1 日付, 3 管理番号 from dual 11 ) t1 12 group by 13 to_char(t1.日付, 'YYYY/MM/DD') 14 order by 15 to_char(t1.日付, 'YYYY/MM/DD') 16 ; 日付 最小管理番号 -------------------- ------------ 2009/05/30 1 2009/05/31 1
最大を求める
SQL> select 2 to_char(t2.日付, 'YYYY/MM/DD') 日付, 3 max(t2.管理番号) 最大管理番号 4 from ( 5 select sysdate 日付, 1 管理番号 from dual union 6 select sysdate 日付, 2 管理番号 from dual union 7 select sysdate 日付, 3 管理番号 from dual union 8 select sysdate+1 日付, 1 管理番号 from dual union 9 select sysdate+1 日付, 2 管理番号 from dual union 10 select sysdate+1 日付, 3 管理番号 from dual 11 ) t2 12 group by 13 to_char(t2.日付, 'YYYY/MM/DD') 14 order by 15 to_char(t2.日付, 'YYYY/MM/DD') 16 ; 日付 最大管理番号 -------------------- ------------ 2009/05/30 3 2009/05/31 3
最小と最大を日付ごとに結合
SQL> select 2 t1_min.日付 日付, 3 t1_min.最小管理番号 最小管理番号, 4 t2_max.最大管理番号 最大管理番号 5 from 6 ( 7 select 8 to_char(t1.日付, 'YYYY/MM/DD') 日付, 9 min(t1.管理番号) 最小管理番号 10 from ( 11 select sysdate 日付, 1 管理番号 from dual union 12 select sysdate 日付, 2 管理番号 from dual union 13 select sysdate 日付, 3 管理番号 from dual union 14 select sysdate+1 日付, 1 管理番号 from dual union 15 select sysdate+1 日付, 2 管理番号 from dual union 16 select sysdate+1 日付, 3 管理番号 from dual 17 ) t1 18 group by 19 to_char(t1.日付, 'YYYY/MM/DD') 20 ) t1_min, 21 ( 22 select 23 to_char(t2.日付, 'YYYY/MM/DD') 日付, 24 max(t2.管理番号) 最大管理番号 25 from ( 26 select sysdate 日付, 1 管理番号 from dual union 27 select sysdate 日付, 2 管理番号 from dual union 28 select sysdate 日付, 3 管理番号 from dual union 29 select sysdate+1 日付, 1 管理番号 from dual union 30 select sysdate+1 日付, 2 管理番号 from dual union 31 select sysdate+1 日付, 3 管理番号 from dual 32 ) t2 33 group by 34 to_char(t2.日付, 'YYYY/MM/DD') 35 ) t2_max 36 where 37 t1_min.日付 = t2_max.日付 38 order by 39 t1_min.日付 40 ; 日付 最小管理番号 最大管理番号 -------------------- ------------ ------------ 2009/05/30 1 3 2009/05/31 1 3
しかし、これはやはりかなり非効率だ。
効率的なやり方 (1度のGROUP BYで最小と最大はとれる)
SQL> select 2 to_char(t1.日付, 'YYYY/MM/DD') 日付, 3 min(t1.管理番号) 最小管理番号, 4 max(t1.管理番号) 最大管理番号 5 from ( 6 select sysdate 日付, 1 管理番号 from dual union 7 select sysdate 日付, 2 管理番号 from dual union 8 select sysdate 日付, 3 管理番号 from dual union 9 select sysdate+1 日付, 1 管理番号 from dual union 10 select sysdate+1 日付, 2 管理番号 from dual union 11 select sysdate+1 日付, 3 管理番号 from dual 12 ) t1 13 group by 14 to_char(t1.日付, 'YYYY/MM/DD') 15 order by 16 to_char(t1.日付, 'YYYY/MM/DD') 17 ; 日付 最小管理番号 最大管理番号 -------------------- ------------ ------------ 2009/05/30 1 3 2009/05/31 1 3
これが効率のよいやり方(というか普通はこうする)。
第105回 Oracleのお勉強 CASE式とDECODEに慣れる
GROUP BYするときに、countだけでは、うまく集計できないことが多々ある。
それはもう結構ある。
そういうときは、sumとCASEもしくは、sumとDECODEである。
CASEとDECODEの違いは、
CASE と DECODE 関数の違い - オラクル・Oracleをマスターするための基本と仕組み
を参考にしていただくとして、ここでは書式に慣れたいと思う。
リンク先で
引用:
DECODE( expr, comparison_expr1, ret_expr1, comparison_expr2, ret_expr2, default_expr ); CASE expr WHEN comparison_expr1 THEN ret_expr1 WHEN comparison_expr2 THEN ret_expr2 ELSE default_expr END
と とてもわかりやすく書き換えられていましたので、大変助かりました。
DECODE( 比較対象の値が, この値なら, ココの値にする, この値なら, ココの値にする, デフォルト ); CASE 比較対象の値が WHEN この値なら THEN ココの値にする WHEN この値なら THEN ココの値にする ELSE デフォルト END
こんな感じに読めるわけですね。
sum と DECODEを使う
前回の
SQL> select 2 to_char(d_create, 'YYYY/MM/DD HH:MI:SS') 日付, 3 c_status ステータス 4 from 5 t_group_date 6 ; 日付 ステータス -------------------------------------- -------------------- 2009/01/01 10:10:10 5 2009/01/01 10:10:11 5 2009/01/02 10:10:10 5 2009/01/02 10:10:11 0
を使って、
「日付ごとに、ステータスが5のものの件数を数える」
SQL> select 2 to_char(d_create, 'YYYY/MM/DD') 日付, 3 sum( decode ( c_status, 4 5, 1, 5 0 6 ) 7 ) 件数 8 from 9 t_group_date 10 group by 11 to_char(d_create, 'YYYY/MM/DD') 12 order by 13 to_char(d_create, 'YYYY/MM/DD') 14 ; 日付 件数 -------------------- ---------- 2009/01/01 2 2009/01/02 1