2012年12月30日日曜日

vmware-toolbox-cmdで仮想ハードディスクを圧縮する

下記環境で、仮想ハードディスクを圧縮する方法。
  • VMware Player 5.0.1
  • VMware Tools 9.2.2.18018
  • Ubuntu 12.04 LTS (ゲストOS)

ディスク領域を事前に割り当てている場合、[仮想マシン設定] > [ハードウェア] > [ハードディスク] > [ユーティリティ]が無効化されてしまい、最適化などを実行できない。

ゲストOSにログイン中に圧縮する方法は、端末から実行する必要がある。VMware Toolsがバージョン9以降GUIがなくなってCUIのみになったらしい。

下記コマンドを実行するとディスクの一覧が表示される。
$ sudo vmware-toolbox-cmd disk list
/
ので、その中からサブコマンドshrinkに、ディスクを指定すれば、圧縮が実行される。
$ sudo vmware-toolbox-cmd disk shrink /
その他の使い方については、helpコマンドを実行すれば確認できる。
$ sudo vmware-toolbox-cmd help disk
$ sudo vmware-toolbox-cmd help

References

USBメモリをshredする

年末の大掃除でUSBメモリを捨てる前にshredしたかったので、Ubuntu 12.04 LTSで行う方法について調べてみた。

shredするにはデバイスファイルを指定しないといけない。そこでまずUSBメモリのデバイスファイルを調べる。端末で下記コマンドを実行すると、デバイスのリストが表示される。
$ sudo parted -l
モデル: VMware, VMware Virtual S (scsi)
ディスク /dev/sda: 21.5GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: msdos

番号  開始    終了    サイズ  タイプ    ファイルシステム  フラグ
 1    1049kB  19.3GB  19.3GB  primary   ext4              boot
 2    19.3GB  21.5GB  2144MB  exnteded
 5    19.3GB  21.5GB  2144MB  logical   linux-swap(v1)

※以下略
「ディスク」に書いてあるのが、各種記録媒体のデバイスファイルの場所(/dev/sdaがVMwareの仮想HDDのデバイスファイル)。それに「番号」を繋げると、その中のパーティンションのデバイスファイルの場所になる(/dev/sda1, dev/sda2, /dev/sda5があることが分かる)。

USBメモリを接続していると同じ形式で表示されるので、目的のデバイスファイルに対してshredコマンドを実行すれば良い。
$ sudo shred -n 1 -v /dev/sdb

References

2012年12月28日金曜日

Getter/Setterを減らす

Getter/Setterばかりが目立つようなクラスは、きっとドメインモデル貧血症に陥っている。だから、もっと振る舞いを持たせて、カラフルな名前を付けたり。それに、Setterで内部状態を外から操作できるようでは、カプセル化しきれていない。状態が変化しないImmutableなクラスを目指して、少なくともSetterは減らしていきたい。ただ、フレームワークが要求したり、と完全に消し去ることはできないと思う。というわけで、なるべくうまく付き合いたい。

なんてことを考えるようになった。そのキッカケや経緯、参照したパターンについてまとめておく。

『オブジェクト指向エクササイズ』("Object Calisthenics") の9つのルールに、Getter/Setterを禁じるものがある。
ルール9:Getter、Setter、プロパティを使用しないこと
Rule 9: No getters/setters/properties
初めてこのルールを知ったときは、意図には同意できたけれど、適用しようとは思わなかった。同意できたのは、単にフィールドをプライベートにして値の取得/設定をすることが、オブジェクト指向の特徴の一つであるカプセル化だという説明に違和感を持っていたから。Getter/Setterを通せばAPI変更に強くなるとは言え、値を自由に設定していたら、隠蔽できているとは思えない。適用しようと思わなかった最大の理由は、今思うと、実装をイメージできなかったからだと思う。だから、適用しようにもできなかった、の方が実態に近い。

「求めるな、命じよ("Tell, don't ask")」なんて言い換えられても、やっぱりよく分からなかったけれど、最近、少しずつ分かってきた気がする。痛い目を見たり(Setterでインスタンスへの参照を返していたせいで意図しない変更を加えてしまったり、名前がgetで始まるメソッドをGetterだと思って気楽に使っていたら思わぬ副作用があって面食らったり)、それで『Java言語で学ぶリファクタリング入門』や『リーダブルコード』、"Effective Java 2nd Edition"の内容を応用しようと試行錯誤したりして、ようやく使う/使わないの判断が少しクリアになった。

例えば、Remove Setting Methodのリファクタリングを適用すると、初期化のためだけのSetterを使わずに済ませられる。代わりに、(デザインパターン"factory method"を適用していたら、factory methodを経由して)コンストラクタで初期化することになる。そのまま、"Effective Java 2nd Edition"の"Item 15: Minimize mutability"してMutableにできれば、Setterは要らなくなる。あるいは、『リーダブルコード』のいう〈カラフルな単語〉を使った名前を付けようとすれば、そんな名前が付けられるくらい十分に抽象化しようとすれば、自然とGetter/Setterのような無味乾燥な名前は相応しくなくなる。

ただ、それでGetter/Setterがなくせるかというと、そうはならないと思う。現実問題、フレームワークから利用されるためにEntity Beanにする必要があるクラスも出てくるし、抽象度の低いクラスで融通が利かなくなる。Getter/Setterを使用しないというのは、あくまでエクササイズのルールであって、実戦における規約ではない。だから、リファクタリングSelf Encapsulate Fieldや"Effective Java 2nd Edition"の"Item 14: In public classes, use accessor methods, not public fields"があるんだと思う。

References


2012年12月24日月曜日

Zen Codingのミニマル・リファレンス

Zen Codingを試してみたら思いの他快適だったので、簡単にまとめておく。

Zen Codingは、HTML/CSSのメタ言語のようなもの。スクリプト言語のように逐次展開もできるし、先にHTMLのテキスト要素を書いてからタグで括ることもできる。

今回まとめるのはHTMLだけ。CSSをまとめないのはSCSSやLESSもあって、SCSSを使い始めているから。少し、調べた限りだと、Zen CodingはSCSSに対応していない。

なお、環境は次の通り。後述の()を使った記法が期待どおり動作しないけれど、それだけのためにエディタを変えるのも何なので。
  • OS: Ubuntu 12.04
  • Editor: gedit 3.4.1 + Zen Coding Plug-in

必要となる最小の操作方法は次の2つ。自分の場合、1つ目だけを使ってまず構造だけ書いていく方が性に合っている。
  • 逐次展開する場合は省略記法で書いては、Ctrl+E
  • テキスト要素をタグで括るにはテキストを選択した状態でCrtrl+Shift+E

まずはひな形。"要素名:DOCTYPEの省略形"と書いて、Ctrl+Eを押すと、DOCTYPE宣言とhtml要素に展開される。html要素には、head要素とbody要素も含まれている。
html:4s
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
  <title></title>
</head>
<body>

</body>
</html>

個々の要素はタグ名をそのまま書けばいい。
p
<p></p>

id属性やclass属性はCSSセレクタのように書ける。
p#id
p.class
<p id="id"></p>
<p class="class"></p>
要素名を省略すると、div要素が補われる。
#id
.class
<div class="class"></div>
<div id="id"></div>
その他の属性は要素名の後に[]で括って書く。
a[target="_blank"]
<pre class="prettyprint">
<a href="" target="_blank"></a>

続いて、ドキュメント構造の表し方。まずは兄弟要素。
h1+p
<h1></h1>
<p></p>
続いて子要素。
ul>li
<ul>
  <li></li>
</ul>
*を使うと繰り返しを表現できる。
ul>li*3
<ul>
  <li></li>
  <li></li>
  <li></li>
</ul>
なお、繰り返しと合わせて$を使うと、連番に展開される。
p#id$*5
<p id="id1"></p>
<p id="id2"></p>
<p id="id3"></p>
<p id="id4"></p>
<p id="id5"></p>

()で括るとグループ化される。はずなのだけれど、これはgeditのZen Coding Plug-in plug-inでは展開されない。残念。
form>(label+input:text)*2+input:button
<form action="">
  <label for=""></label>
  <input type="text" name="" id="" />
  <label for=""></label>
  <input type="text" name="" id="" />
  <input type="button" value="" />
</form>

他にも色々とできるみたいだけれど、まずはこれだけ使えるだけでも、随分とサクサクと入力できるように思う。

References

2012年12月22日土曜日

ジェネリクスでAPIを柔軟にする

あるクラスの任意のサブクラスのリストを引数に取れるメソッドは、ジェネリクスの型引数にバインドされワイルドカードを指定すれば書ける。

当てずっぽうで書いたらダメだったから何とかその場しのぎのコードを書いていたのだけれど、その後読んだ"Effective Java 2nd Edition"の"Chapter 5 Generics"でいくぶんスッキリしたので整理してみる。

まずリストじゃない場合で前提の確認。Superクラスを継承するSubクラスがあるとき、どちらも引数に取れるメソッドはこう書ける。こう定義しておけば、どちらを渡しても大丈夫。
public void printInstance(Super instance) {
    System.out.println(instance);
}
printInstance(new Super());
printInstance(new Sub());

リストでも同じようにいけるかな? と思って、当てずっぽうで書いたダメな例がこれ。こう書いて、Subのリストを渡そうとすると、コンパイルエラーになる。実は、そもそも、List<Sub>List<Super>のサブクラスではない。
public void printList(List<Super> list) {
    System.out.println(lst);
}
printList(new ArrayList<Sub>);

この場合はBounded wildcard type (バインドされたワイルドカードタイプ)を使って、こう書く。Superのサブクラスのリストだけじゃなくて、Superのリストも渡せる。
public void printList(List<? extends Super> list) {
    System.out.println(lst);
}

反対にあるクラスのスーパークラスのリストとそのクラス自身のリストを引数に取れるようにも書ける。その場合は、<? extends Super>の代わりに<? super Sub>を使う。

使い分けの指針には"PECS"や"get-put principle"がある。よくかみ砕けていないのだけれど、同じことを言っているように思う。こうしておくと型安全で使いやすいAPIになるとのこと。
PECS stands for producer-extends, consumer-super
"Effective Java 2nd Edition", Item 28: Use bounded wilidcards to increase flexibility
構造から値を取得する (get) だけの場合には extends ワイルドカードを使い、構造の中に値を格納する (put) だけの場合には super ワイルドカードを使い、そして両方を行う場合にはワイルドカードを使ってはなりません。
『Java の理論と実践: Generics のワイルドカードを使いこなす、第 2 回』

References

2012年12月19日水曜日

Rでオブジェクト指向 (S3)

RにはS3, S4, R5の3種類のクラスがある。S3はclass属性で判定しているだけの緩やかな型付け。S4は厳格に定義しておく必要がある厳格な型付け。R5は2.12で追加された新しいクラスで、厳格さはS3とS4の中間。参照渡しという大きな特徴がある。

今回はS3クラスについて。まだS4, R5は理解していないし、"Google's R Style Guide"がS3を推奨しているので、まずはS3から勉強している。
Use S3 objects and methods unless there is a strong reason to use S4 objects or methods.
Google's R Style Guide
S3クラスができるのは、class属性と汎用関数を使ってポリモーフィズムを与えること。つまり、クラスごとに同じ名前で異なる実装の関数を呼び出せる。printやsummaryが分かりやすい例だと思う。

自分で簡単な例を実装してみる。

まず、インスタンスにクラスを教える。S3クラスではclass属性にベクトルを設定するだけ。ベクトルなので、複数のクラスを設定できる。この例では、hogeクラスやfugaクラスを設定している。
a <- 1:10
attr(a, "class") <- "hoge"

b <- 1:10
attr(b, "class") <- c("fuga", "hoge")

c <- 1:10
続いて、汎用関数を宣言・実装する。Javaでいう抽象メソッドを宣言してから、クラスごとに実装していくイメージ。最後の.defaultはデフォルト実装で、対応するクラスがないときに呼ばれる。
calc <- function(x, ...) {
  UseMethod("calc")
}

calc.hoge <- function(x){
  return (x + x)
}

calc.fuga <- function(x) {
  return (x * x)
}

calc.default <- function(x) {
  return (x + 1)
}
実際に呼び出すと、class属性に応じて違う実装が呼び出されていることが確認できる。calc(b)でcalc.fugaが呼ばれていることから、ベクトルを先頭から探しているみたい。
calc(a)
# calc.hoge is called
# 2  4  6  8 10 12 14 16 18 20

calc(b)
# calc.fuga is called
# 1   4   9  16  25  36  49  64  81 100

calc(c)
# calc.default is called
# 2  3  4  5  6  7  8  9 10 11
これでポリモーフィズムが使える。ということは、ポリモーフィズムを活用しているデザインパターンも適用できるはず。

References

2012年12月18日火曜日

データ可視化の7ステージ

"Visualizaing Data" (邦訳『ビジュアライジング・データ』) で紹介されていた、データ可視化の7ステージ(The Seven Stages of Visualizing Data)。分析に手を付ける前に思い出すと、スムーズに課題を整理できる。でも、出てきた課題をそれぞれどう解決するかは別の話。
  1. Acquire: データを手に入れる。
  2. Parse: 生のデータを構造化する。
  3. Filter: 不要なデータを取り除く。
  4. Mine: 統計・マイニング手法を適用する。
  5. Represent: 基本的な可視化モデル(棒グラフ、散布図、ツリーなど)で表現する。
  6. Refine: 基本的な可視化モデルを洗練させる。
  7. Interact: 可視化モデルを操作できるようにする。

References


2012年12月16日日曜日

任意の行でデバッグを開始する

Python 2.7.3で、コード中の任意の位置でデバッガpdbを起動する方法。

このコードをブレークしたい行の手前に挿入しておく。
import pdb; pdb.set_trace()
挿入したスクリプトをシェルで実行すると、デバッガが起動する。よく使うコマンドは次の5つ。
s(tep)      # ステップイン
n(ext)      # ステップオーバー
r(eturn)    # ステップアウト

b(reak) n   # 実行中のファイルのn行目にブレークポイントを設定
c(ontinue)  # 次のブレークポイントまで実行

l(ist)      # 実行中のコードを表示
h(elp)      # ヘルプを表示
q(uit)      # デバッガを終了
デバッガコマンド以外はPythonの文として実行されるので、変数の値を確認したりできる。
print varname

References