南極の図書館

ペンギンが寝ていた…。

「スティーブジョブズ」を読みはじめた

とても良い本だと思う。雰囲気としては「福翁自伝」のようだと感じる。
常識や決まりなどには捕われず自分がやりたいことをやる。その快活さと大きな志とが、福沢諭吉にも、ジョブズにもある。


読んでみて、私が意外だなと思ったのは大きく二つ、まずは「天才」では無かったこと。
リード大に入った頃はカリスマ性というほどのものは無く、後天的なものだということが書かれている。
もうひとつは、感情表現が下手だということ。
これは、意外ではないという人も多そうだが、ウォズのおやじにいろいろ言われて泣いてしまうところなど、クールとは程遠い人物であったようだ。
また、読んでいるとジョブズよりもウォズの方に感情移入してしまうところが多いのだが、エンジニアの大半はそうなんじゃないかなと思う。


ジョブズ関連の本を多く読んでいる人には「新しい内容はない」とも言われているようだが、私はそういう本は読んでいないし、楽しく読めている。
もちろん例の「祝辞」や、いくつものプレゼンテーションは見ているが、ちょうどそれが前提となって、すんなり読めている。
逆に、それらを見ていないのなら、その都度Youtubeを見ることになるのだろう。


あーだこーだ言わずに、まずは読んでおこうという本だと思う。


Eclipseをvimっぽく使うVrapperプラグインを入れた

「イージーモードが許されるのは小学生までだよねー。」

という有名なネタがある。
それはゲームの話なわけだが、仮にゲームはそうだとして、現実は、

「イージーモードに入れるのは工夫をした人間だけだよね。」

というのが正しいと思っている。
何かをやりとげなければならない。その志が高いほど、何も考えずにぶつかっていけば難易度が高くなっていく。
ゲームでいえばハードモードとかルナティックとかいうものになる。


私は最近、膨大な量のコードを読んでいて、もともと作業量が限界に近かった。
ジリ貧になっていたところ、今週から更に忙しくなり、これはもう絶対無理という感じに。
その一番大きな原因はEclipseの習熟度の低さというか、思うような移動ができないことだ。


「もうちょっとVimみたいに動いてみろよ!」


そんなことも言いたくなる。
ああ、そうだ。
考えてみたら「もうちょっとVimみたいに動いてみろよ!」と思う人はいくらでもいるだろう。
なら、解決策もいくつかあるだろう、と検索すると出てくる。


いくつかあったが、Vrapperというのを選んだ。
Vrapper — Vim-like editing in Eclipse
Eclipseの更新サイトに入れるならこれ。
http://vrapper.sourceforge.net/update-site/stable


いくつか設定をしたけどそれは今度書くので割愛。
結果だけ書くと、超便利。
今までハードモードを強制されていたゲームがイージーモードになった。
ゲームじゃなくて仕事だけど。


こうなるともう楽しくなってくるもので、今日はたっぷりと働いてきたし、明日からのスケジュールにも光が射した。


「イージーモードの入り方を探さないなんて、小学生までだよね。」

SoftbankからauのiPhone4Sに乗り換えた感想

数日使ってみたので、つらつらと書いていく。
主にezwebメールに対する不満だが、考えると最初はSoftbankもそうだったし、Androidも各社どうしようもなかったので、やむなしとも思う。

3GSと4Sの違い

ファミコンスーパーファミコンくらい違った。特に画面。


デザインは背面カーブの方が好きなんだけど、これでもさすがAppleというくらいはカッコイイ。
持ってはじめて気づくのは、4Sは一回り小さい。3GSは太ってるなという感じ。
それと、ホームボタンと画面の感触が良くなった感じ。気のせいかもしれないけど柔らかい。

結局、Softbankとauどちらがいいのか

電波が悪すぎるSoftbank、メールがひどすぎるauということで、引き分け。

電波

期待したほどの差は無かった。(私の活動範囲では。)
ただ、山手線を移動してる最中でもガンガン切れるソフトバンクと違って「入るべき」ところではきっちり入るのがau。
地下鉄などはあまり変わらない。旧800MHz帯が使えないとこんなもんだよね、という感じ。


それより、Softbankを使っていると「ソフバンだから入らなくても仕方ないか」とか「電話したいけど、ここってソフバンの電波入るかな」などと考え、実際に電波が入らない辛さよりも精神的な苦痛の方が大きかったので、それが無くなっただけで十分価値があった。

ezwebメール

3つ文句がある。

自動受信は15分に1回だけ

まず「自動受信は15分に1回」しかできない。
そのため「ezwebメアド取得→me.comに転送設定」する人が多いと思うけど(店頭でも勧められた)、それってただの転送だから。
me.comにメールが来る→手動でezwebを受信する→返信、という手順が必要。
怠慢、短気、傲慢なプログラマにこんな手順やらせたら精神崩壊してもおかしくない。
me.comにきたものをそのまま「返信」したい。むしろ何も考えないで返信したらそうなって「あれ?違うアドレスで来ましたよ」と言われた。
もうezweb要らないんだけど、1月までガマンできるならキャリアメールの方が何も言われなくていいし、耐えるしかない。(「me.comって何?」とか言われるのが面倒。)

絵文字

絵文字が使えない。おそらく全部。
他社に使えないだけならともかく、ezweb同士でも使えない。なんだこれ。
iPhone4Sにして、しかもauだからモテる!!なんて考えてたら、絵文字も使えないダメ野郎に。
これは絵文字アプリを入れればなんとかなりそうなので、どうしても絵文字送りたくなったら探してみる。(結構どうでもいい。)

iMessage未対応

MMSもダメ。1月対応予定とか。
既に解約したiPhone3GSでiMessageが出来るだけに、なんだかなぁと。


などと文句ばかりですが、私は性格上、Softbankのまま機種変更したら「auにしていたらどうなっていたか」と考え、比較記事を読んでも「そんなこと言っても体験してみないとわかんないよな」とモヤモヤしていたことは間違いないので、乗り換えは必然でした。
結論は最初に書いたとおり現時点では引き分けですが、来年1月頃からauの方が良くなるんじゃないかと思います。

Redmineプラグインチュートリアルについて

Redmineのプラグインを作ろうと思い、redmine.jpを調べてみた。
探してみると「その他の文書」に「プラグインの開発」の項目がある。
プラグインの開発 | Redmine.JP
そこからredmine.orgのチュートリアルの日本語訳を見つけたのでやってみた。
プラグイン チュートリアル - r-labs

チュートリアルの実施

結論から言うと、プラグインを:project_menuにする箇所でエラーとなってしまった。
「メニューを拡張する。」の「プロジェクトメニューを拡張する。」にあるこのコード。

def index
  @project = Project.find(params[:project_id])
  @polls = Poll.find(:all) # @project.polls
end

controllerでvoteを呼んだときにparams[:project_id]に何も入っていないので、エラーとなる。

  @project = Project.find(params[:project_id])
  rescue ActiveRecord::RecordNotFound
    render_404
  end

ちなみに、こうするとちゃんと404が出る。(Redmine本体のコードがこうだった。)
チュートリアルで見落としたところは無いようだったので、自分で書いてみた。
毎回パラメータで渡すのは嫌な感じもあるけど、どうなんだろう。
もっと本家のコードを見て書き方を覚えていかないと。

差分

チュートリアルに記載されているコードとの差分を置いておきます。
vendor/plugins/redmine_polls/app/controllers/polls_controller.rb

class PollsController < ApplicationController
……
  def vote
    poll = Poll.find(params[:id])
    poll.vote(params[:answer])
    if poll.save
      flash[:notice] = 'Vote saved.'
-     redirect_to :action => 'index'
+     redirect_to :action => 'index', :project_id => params[:project_id]
    end
  end
……
end

vendor/plugins/redmine_polls/app/views/polls/index.html.erb

<h2>Polls</h2>
 <% @polls.each do |poll| %>
  <p>
  <%= poll[:question] %>?
-  <%= link_to 'Yes', {:action => 'vote', :id => poll[:id], :answer => 'yes'}, :method => :post %> (<%= poll[:yes] %>) /
-  <%= link_to 'No', {:action => 'vote', :id => poll[:id], :answer => 'no'}, :method => :post %> (<%= poll[:no] %>)
+  <%= link_to 'Yes', {:action => 'vote', :id => poll[:id], :answer => 'yes', :project_id => params[:project_id]}, :method => :post %> (<%= poll[:yes] %>) /
+  <%= link_to 'No', {:action => 'vote', :id => poll[:id], :answer => 'no', :project_id => params[:project_id]}, :method => :post %> (<%= poll[:no] %>)
  </p>
<% end %>

「リファクタリング」の完全読破。その8、7章後半

前回に引き続き、7章の後半。
8月に読み終わる予定が、もう10月も中旬に。

委譲の隠蔽(P157)

カプセル化は、唯一のとは言わないまでも、オブジェクト指向技術の鍵である。

class Client... 
  //before
  _manager = john.getDepartment().getManager();
  //after
  _manager = john.getManager();  }


class Person{
  Department _department;
  public void setDepartment(Department arg){
    _department = arg;
  }

  //before
  public Department getDepartment(){
    return _department;
  }
  
  //after  委譲メソッドを作り、getDepartment()は削除する。
  public Person getManager() {
    return _department.getManager();
  }
}

class Department{
  //このクラスはリファクタリング前後で変更なし。
  private Person _manager;
  public Department(Person manager){
    _manager = manager;
  }
  public Person getManager(){
    return _manager;
  }
}
仲介人の除去(P160)

委譲の隠蔽の逆。
隠蔽をどの程度施すのか見極めるのは困難で、システムが変化すればその基準も変化していく。
適当だったカプセル化もしばらくすると扱いにくくなるが、それは悪いことではない。ひたすら直すこと。

外部メソッドの導入(P162)

「利用中のサーバクラスにメソッドを追加する必要があるが、そのクラスを変更できない」場合に行う。


約束は二つ。
作成するメソッドの第一引数は、サーバクラスのインスタンスとする。
決まったコメントをつける。(//外部メソッド;<サーバ名>クラスにあるべき)


コードの例が古すぎてEclipseが全力で取り消し線をつけてくれるんだけど、ここはDateクラスほどいい例が他に浮かばないのでそのまま写経してみた。
当時のDateクラスは、どこのシステムでも自社フレームワークとして拡張してるんじゃないかな。

Date newStart = new Date(previousEnd.getYear(), previousEnd.getMonth(), previousEnd.getDate() + 1);
↓
Date newStart = nextDay(previousEnd);
private static Date nextDay(Date arg) {
//外部メソッド;Dateクラスにあるべき
  return new Date(arg.getYear(), arg.getMonth(), arg.getDate() + 1);
}
局所的拡張の導入(P164)

外部メソッドの導入は対象メソッドが2つまで、こちらは3つ以上のときに行う。
サブクラスかラッパーか、どちらでも採用できるが、ファウラーは可能ならば作業の少ないサブクラス化を勧めている。
新クラスには元のオブジェクトを引数とする変換用コンストラクタを作る。サブクラスにしたならsuperで、ラッパーなら委譲フィールドを設定する。
以下はサブクラスの場合の手順で、ラッパーの場合については割愛する。

Date newStart = new Date(previousEnd.getYear(), previousEnd.getMonth(), previousEnd.getDate() + 1);
↓
Date newStart = new MfDate(previousEnd).nextDay();
public class MfDate extends Date{
  public MfDate(String dateString) {
    super(dateString);
  }
  public MfDate(Date arg) {
    super(arg.getTime());
  }
  Date nextDay() {
    return new Date(getYear(), getMonth(), getDate() + 1);
  }
}


次回は8章だけど、先は長い。