新着記事
エラー処理の書き方について、紹介したいと思います。
早速ですが、下記の前提条件を設定します。
・ある処理を1つの関数で実装した。
・この処理には、エラー処理(エラーとなる条件の引っ掛け方)として is_error1 と is_error2 の2つがある。
・エラー処理の結果は、エラーでなければ(PASS、合格) true を、エラーであれば(FAIL、不合格) false を返すものする。
リスト1
boolean function1(someObject obj) {
if(!is_error1(obj)) {
if(!is_error2(obj)) {
obj.somethingToDo();
return true;
} else {
msg("error2!");
return false;
}
} else {
msg("error1!");
return false;
}
}
リスト1のように実装した場合、正常系のコードを追うのに2階層分もぐらなければなりません。また、各階層に異常系のコードがあるため、煩雑であるように見えます。
リスト2
boolean function2(someObject obj) {
if(is_error1(obj)) {
msg("error1!");
return false;
}
if(is_error2(obj)) {
msg("error2!");
return false;
}
obj.somethingToDo();
return true;
}
リスト2は、エラー処理を順にくぐらせて、引っ掛かったときに関数を抜けるよう構造を組み替えたものです。異常系のコードと正常系のコードは明確に分離されているため、リスト1に比べて見通しがよくなっていると思います。
次は、少し複雑なエラー処理を見てみましょう。エラーとなる条件は2つあるのですが、一方が(排他的に)エラーのときのみ正常としたいとします。
リスト3
boolean function3(someObject obj) {
if(!is_error1(obj)) {
if(!is_error2(obj)) {
msg("no error!");
return false;
} else {
obj.somethingToDo();
return true;
}
} else {
if(!is_error2(obj)) {
obj.somethingToDo();
return true;
} else {
msg("both error!");
return false;
}
}
}
この要件は2つのエラー処理について真真、真偽、偽真、偽偽の4パターンがあり、素直に実装すればリスト3のようになります。すべての条件をカバーしているため要件を満足しています。
リスト4
boolean function2(someObject obj) {
if(!is_error1(obj) && !is_error2(obj)) {
msg("no error!");
return false;
}
if(is_error1(obj) && is_error2(obj)) {
msg("both error!");
return false;
}
obj.somethingToDo();
return true;
}
リスト4は異常系を前半に、正常系を後半に置くよう構造を変えた実装です。if文の中の記述が複雑になっていますが、正常系のコードは1つのみ記述すればいいようになっています。正常系のコードが複雑になれば、リスト4の方が有利です。
リスト1とリスト3は、異常系の処理を else文 に排除する考え方です。一方、リスト2とリスト4は異常系の処理を関数のはじめで追い出す考え方です。関数のどこでエラーを捕まえるか(あるいは逃がすか)の違いしかありません。コードを追うときはリスト1よりリスト2、リスト3よりリスト4の方が直感的に理解できると思いますので、エラー処理を記述するときは積極的にこの書き方を意識してみてはいかがでしょうか。
1.記憶先について
GNOME端末で起動したviにテキストを貼り付ける時、3種類の記憶先が使えます。
その1.他のアプリケーションから「コピー」なり「切り取り」なりで「貼り付け」ができる記憶先
その2.マウスカーソルを使ってテキストを反転させた時に記憶される記憶先
その3.viのコマンドのy(行コピー)なりd(行切り取り)などをタイプした時に記憶される記憶先
これら3つは、互いに独立した記憶先なので、場面場面で3つのクリップボードが使えます。
2.貼り付け方法
これら3つの記憶先からの貼り付け方法をご説明します。
その1.「Ctrl + Shift + Ins」 キーで貼り付け
その2.「Shift + Ins」 キーまたは「マウスのホイールボタン」で貼り付け
その3.viのコマンドのp(カーソルの下の行に貼り付け)なりP(カーソルの上の行に貼り付け)なりで貼り付け
どんな時に役に立つか、私の実体験で1つご紹介します。
3.実務で使ってみる (その1)
3.1 シナリオ概要
1つの手順を複数のサーバーに適用してまわります。手順書や設定ファイルのいろいろな箇所に、サーバー名を埋め込みながら作業を進めるのですが、このテクを覚えておけばコピペに要するキータイプ及び画面切り替えをぐんと減らす事ができます。
・対象のサーバー名一覧(記憶先「その1」にコピー)
server01
server02
server03
・手順(コマンド)向けテキスト(記憶先「その2」にコピー)
cp /etc/sysconfig/network /tmp/network
vi /etc/sysconfig/network
diff /tmp/network /etc/sysconfig/network
3c3
< HOSTNAME=template.intfloat.com
---
> HOSTNAME=server01.intfloat.com
3.2 使い方
対象のサーバー名を「その1」でコピーします。
発行するコマンド(手順書の一部、テキスト)を「その2」でなぞって、端末に貼り付けて実行していきます。設定ファイルをviで編集するときは「その3」を使ってアグレッシブに編集します。一部、サーバー名を置き換える箇所がありますので、ここでは「その1」から貼り付けます。
あとはサーバーの数だけこの手順を繰り返していきます。
4.実務で使ってみる (その2)
4.1 シナリオ概要
単に、2種類の文字列をコピーしたい。function() の引数に、arg1 を貼り付けるのが目標です。
function(); # 「その1」にコピー
arg1 # 「その2」にコピー
4.2 使い方
function(); を「その1」に、arg1 を「その2」にコピーします。端末にて、まず「その1」から貼り付けます。次に、カーソルを挿入したい場所(かっこ内)に移動して、「その2」から貼り付けます。これで、貼り付け元のウィンドウと端末とを2往復せずとも2種類の文字列をコピー&ペーストできます。
5.結び
より上手に使いこなすポイントもご紹介しましょう。頻繁にコピー&ペーストが必要な箇所は「その2」を使いましょう。コピーする操作は、コピーしたいテキストをマウスで反転させるだけです。逆に、作業を通して使いたいものは、「その2」に比べて、誤ってコピーして上書きするリスクが低いので、「その1」でコピーしておきます。この2つさえ覚えておけば、vi専用の「その3」も交えつつ、GNOME端末のviライフがより快適になるはずです。
すべてキーボードで操作しないとヤだよ!(マウス操作は間違いやすいもの!)って方にはあまり魅力的ではないテクですが、そうでなければ是非使ってみてください。(※このテクを使ってサーバーを操作する時は、特に「その2」の行末の改行についてご注意下さい。)
開発部の「カエル」です。
入社して1週間と2日目になります。
プログラマ歴は6年で、今まではVB.NETやASP.NETというプログラミング言語で業務用のシステム開発を多く携わっていました。
ですので、Perlでの開発は初めてで日々苦戦して習得しています。
技術的に未熟な為、覚えることがたくさんありますので、
こうした習得した技術をスタッフブログで発信していく予定です。
どうぞ宜しくお願いします。
↓最後に独り言。
*。・:*:・*。・:*:・*。・:*:・*。・:*:・*。・:*:・*。・:*:・*。・:*:・*。・:*:・*。・:*:・*。・:*:・
梅雨に入って、雨嫌いな方にとっては憂鬱な日々が続きますが、
この季節を楽しむのもどうでしょうか?
私は、週末紫陽花を観に行こうかと考えています。
雨が降ってテンションが若干下がりますが、
今日も1日頑張っていきましょう!
こんにちは。くすのきです。
perlのsplit関数の挙動で引っかかったのでまとめます。
■シナリオ
・様々な改行コードが混ざっているイケてない文字列がある。
・\r\n,\r,\nのいずれも一つの改行として文字列を分割したい。
■最初に書いたコード
単純に括弧でくくって3種類の改行コードを記述。
(ソースコード)
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my($str, @str);
$str = "hoge\r\nhoge\rhoge\n";
@str = split(/(\r\n|\r|\n)/, $str);
map {if(defined($_)){s/\r/R/g; s/\n/N/g;}} @str; # \r\nを可視化
print Dumper(\@str);
exit;
括弧を使用するとセパレータが結果配列に含まれてしまう。
(実行結果)
$VAR1 = [
'hoge',
'RN',
'hoge',
'R',
'hoge',
'N'
];
■次に書いたコード
セパレータを含まないように、?:を記述。
(ソースコード)
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my($str, @str);
$str = "hoge\r\nhoge\rhoge\n";
@str = split(/(?:\r\n|\r|\n)/, $str);
map {if(defined($_)){s/\r/R/g; s/\n/N/g;}} @str; # \r\nを可視化
print Dumper(\@str);
exit;
意図した通りの結果配列になる。
(実行結果)
$VAR1 = [
'hoge',
'hoge',
'hoge'
];
■ラクダ本を見て、「こんな書き方するわけがない」と思いつつ書いた対照実験コード
改行コードごとに括弧でくくって記述。
(ソースコード)
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my($str, @str);
$str = "hoge\r\nhoge\rhoge\n";
@str = split(/(\r\n)|(\r)|(\n)/, $str);
map {if(defined($_)){s/\r/R/g; s/\n/N/g;}} @str; # \r\nを可視化
print Dumper(\@str);
exit;
マッチしなかった括弧については、undefが結果配列に含まれる。
(実行結果)
$VAR1 = [
'hoge',
'RN',
undef,
undef,
'hoge',
undef,
'R',
undef,
'hoge',
undef,
undef,
'N'
];
他にもセパレータがスペース1個の場合(/ /ではなく" "を指定した場合)にも、特別な挙動を示すようです。
(awkのデフォルト動作と同じ挙動。先頭のスペースを削除し、/ +/でsplitする。)
今回の話からはちょっとずれるため、実験コードは割愛します。
興味のある方は実験コードを書いてみてください。
こんにちは、hassen です
突然ですが、みなさんは編集したいファイルを開くとき、どうしてますか?
エディタのファイルを開くコマンドから、ファイルのパスを指定して開く?
エクスプローラーのようなファイラーから、ディレクトリを辿って開く?
Eclipse のような IDE を使っている人なら、プロジェクトごとに関連ファイル一覧を表示してくれたりするかもしれませんが、
そうでなければ、深い階層にあるようなファイルを開く作業って結構面倒だったりしますよね。
よく使うファイルはショートカットを作成したり、ブックマークのような機能を使っている人もいるかと思います。
ここでは、Emacs でファイルを素早く開くための方法を、いくつか紹介してみます。
ブックマーク (bookmark)
Emacs に標準で付属している機能です。いわゆる「お気にいり」というやつ。
ブラウザのブックマークなんかと同じ感覚なので、わかりやすいですね。
ブックマークの特徴は、ファイルの「どの部分を編集しているか」という位置を記憶しておけること。
ひとつのファイルに対して、複数のブックマークをつけることも可能です。
大きいファイルの「この場所をよく編集する」という場合に便利です。
また、dired バッファをブックマークすることで、ディレクトリのブックマークも可能です。
主な使い方は以下のとおり。
「C-x r m」カレントバッファをブックマークに追加 (デフォルトではファイル名=ブックマーク名)
「C-x r b」ブックマーク名を指定して開く
「C-x r l」ブックマークの一覧を表示
「d」一覧表示で、ブックマークに削除マークをつける
「x」一覧表示で、削除マークのついたものを削除
filecache
これも Emacs 標準の機能。
あらかじめディレクトリ名のリストを作成しておくと、カレントディレクトリがどこであるかにかかわらず、指定したディレクトリ以下のファイルはパスを辿らずに簡単に補完して開くことができます。
「特定のディレクトリ以下のファイルをよく開くんだけど、全部をブックマークに登録するには多すぎる」「ディレクトリ内にファイルが増えるたびにブックマークに追加するのが面倒」「ていうかいちいちブックマーク開くのが面倒、普通に C-x C-f でファイル開きたい」という場合に便利です。
使い方ですが、まずは下記のようにディレクトリのリストを設定します。
単独のファイルを指定することもできます。
(require 'filecache)
(file-cache-add-directory-list
(list "~" "~/bin/" "~/lib/")) ;; ディレクトリを追加
(file-cache-add-file-list
(list "~/memo/memo.txt")) ;; ファイルを追加
(define-key minibuffer-local-completion-map "\C-c\C-i"
'file-cache-minibuffer-complete)
そして、C-x C-f でファイル名を入力。このときディレクトリのパスは気にせず、とにかくファイル名だけ打てばよいです。
そして、補完。ここでは「C-c C-i」(「C-c TAB」)に filecache の補完コマンドを割り当てています。(普段どおりの補完は「TAB」でOKです)
ディレクトリのパスまで含めて、ファイル名が補完されましたね?
(同じファイル名のものが複数該当した場合は、何度か「C-c C-i」を繰り返し打ってみましょう)



次回は、最近開いたファイルの履歴を利用して、ファイルを開く方法です。

最近のコメント