2012/05/30

BackgroundWorker 内で DataContext を使うとき

DataContext を取得するのは UI スレッドからでしか無理のようだ。例外が発生する。
なので BackgroundWorker で DataContext を取得したい場合、こんな風に UI スレッドで動かしてやらないといけない。
Action action = () =>
{
    var hoge = (HogeViewModel)this.DataContext;
    // do something ...
}
tihs.Dispatcher.Invoke(action);

WPFのドラッグアンドドロップで処理を行う場合

エクスプローラとかからディレクトリを D & D して処理を行う場合、よほど軽いすぐ終わる処理でない限りは BackgroundWorker などで別スレッドにしたほうがいいみたい。
Window_Drop ハンドラ内で処理していたら、処理が終わるまでエクスプローラがロックされたような状態になってしまう。

2012/05/29

WPFでファイルやディレクトリのドラッグアンドドロップ処理

例えば Window に対して行うなら、Window の AllowDrop を true にして、DragOver と Drop イベントにハンドラを設定すればできる。
イベント名が違うだけで、これも WinForms 時代と変わらないね。
DataFormats って文字列の定数クラスなのね。
const じゃなくて readonly なのは理由があるのだろうか?

2012/05/28

WPFで未処理の例外を一括処理

アプリケーション開発の定番の例外一括処理。
WPF も Windows Forms 時代とたいして変わらないね。
DispatcherUnhandledException はコードビハインドではなく、App.xaml に記述することもできるけど、UIスレッドで発生した時の DispatcherUnhandledException と UIスレッド以外で発生した時の UnhandledException はセットで考えるべきだと思うので、見通しが良いように一括で設定するようにしてる。

2012/05/19

特定のインターフェースを実装しているかどうかを調べる

プロパティの型が IEnumerable かどうかを判別したかった。
// 基底クラス
public class Base {}

// サブクラス
public class SubClass : Base {}

// とあるクラス
public class Foo
{
    // 実体は List だけど IEnumerable として公開
    public IEnumerable Classes
    {
        get { return new List<SubClass>(); }
    }
}
これでリフレクションを用いて、Classes プロパティが IEnumerable と互換性があるかどうかを調べたい。
var propType = typeof(Foo).GetProperty("Classes").PropertyType;
bool impl = false;

// これは false
impl = propType.IsSubclassOf(typeof(IEnumerable));

// これで IEnumerable を実装していることは判別できた
var filter = new System.Reflection.TypeFilter((t, obj) => t == (Type)obj);
impl = propType.FindInterfaces(filter, typeof(IEnumerable)) > 0;

// 最終的にはこう
impl = impl && propType.IsGenericType && propType.GetGenericParameters()[0].IsSubclassOf(typeof(Base));
かなり長ったらしくてめんどくさい。
なんか簡単な方法があるはずだと思って調べてみたら、これだけでできた。
typeof(IEnumerable<Base>).IsAssignableFrom(propType)
代入可能かどうかで調べたらよかったのか。

2012/05/16

chrome に期間限定系の Google 検索を登録すると便利

Googleの検索結果を常に更新が1年以内のものに限定するChrome Extension「ato-ichinen」が便利 | Last Day. jp
けっこう需要あるみたいですね、これ。
技術系の調べ物をしている時に昔のページが検索に引っかかって、バージョンが古くて微妙に違うとかよくあるので、一年以内とか一ヶ月以内はよく使うね。
なので、自分の場合はよく使うものを検索エンジンに登録してる。
登録してるのはこんな感じ。
検索エンジン キーワード URI
google(1年) gy https://www.google.co.jp/search?q=%s&tbs=qdr:y
google(半年) gh https://www.google.co.jp/search?q=%s&tbs=qdr:m6
google(3ヶ月) gq https://www.google.co.jp/search?q=%s&tbs=qdr:m3
google(1ヶ月) gm https://www.google.co.jp/search?q=%s&tbs=qdr:m
拡張機能もいいけれど、キーボードだけで操作できるし、期間も細かく区切れるので、自分にはこっちのほうが便利かな。

2012/05/15

Rails プロジェクトの初期化

Ubuntu 12.04 上にとりあえず簡単な Rails プロジェクトを作成した。
このあたりの作業は毎回ほぼ同じになるのでログとして残しておこう。
# デフォルト設定の確認
$ cat ~/.railsrc
-T -d postgresql --skip-bundle
$ mkdir projects/new_prj $ cd projects/new_prj $ bundle init $ echo "gem 'rails', '3.2.3'" >> Gemfile $ bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/......... Installing rake (0.9.2.2) Installing i18n (0.6.0) Installing multi_json (1.3.5) Installing activesupport (3.2.3) Installing builder (3.0.0) Installing activemodel (3.2.3) Installing erubis (2.7.0) Installing journey (1.0.3) Installing rack (1.4.1) Installing rack-cache (1.2) Installing rack-test (0.6.1) Installing hike (1.2.1) Installing tilt (1.3.3) Installing sprockets (2.1.3) Installing actionpack (3.2.3) Installing mime-types (1.18) Installing polyglot (0.3.3) Installing treetop (1.4.10) Installing mail (2.4.4) Installing actionmailer (3.2.3) Installing arel (3.0.2) Installing tzinfo (0.3.33) Installing activerecord (3.2.3) Installing activeresource (3.2.3) Using bundler (1.1.3) Installing json (1.7.3) with native extensions Installing rack-ssl (1.3.2) Installing rdoc (3.12) Installing thor (0.14.6) Installing railties (3.2.3) Installing rails (3.2.3) Your bundle is complete! It was installed into ./vendor/bundle Post-install message from rdoc: Depending on your version of ruby, you may need to install ruby rdoc/ri data: <= 1.8.6 : unsupported = 1.8.7 : gem install rdoc-data; rdoc-data --install = 1.9.1 : gem install rdoc-data; rdoc-data --install >= 1.9.2 : nothing to do! Yay!
$ bundle exec rails new .
Using -T -d postgresql --skip-bundle from /home/pinzolo/.railsrc exist create README.rdoc create Rakefile create config.ru create .gitignore conflict Gemfile Overwrite /home/pinzolo/projects/expns/Gemfile? (enter "h" for help) [Ynaqdh] Y force Gemfile create app create app/assets/images/rails.png create app/assets/javascripts/application.js create app/assets/stylesheets/application.css create app/controllers/application_controller.rb create app/helpers/application_helper.rb create app/mailers create app/models create app/views/layouts/application.html.erb create app/mailers/.gitkeep create app/models/.gitkeep create config create config/routes.rb create config/application.rb create config/environment.rb create config/environments create config/environments/development.rb create config/environments/production.rb create config/environments/test.rb create config/initializers create config/initializers/backtrace_silencers.rb create config/initializers/inflections.rb create config/initializers/mime_types.rb create config/initializers/secret_token.rb create config/initializers/session_store.rb create config/initializers/wrap_parameters.rb create config/locales create config/locales/en.yml create config/boot.rb create config/database.yml create db create db/seeds.rb create doc create doc/README_FOR_APP create lib create lib/tasks create lib/tasks/.gitkeep create lib/assets create lib/assets/.gitkeep create log create log/.gitkeep create public create public/404.html create public/422.html create public/500.html create public/favicon.ico create public/index.html create public/robots.txt create script create script/rails create tmp/cache create tmp/cache/assets create vendor/assets/javascripts create vendor/assets/javascripts/.gitkeep create vendor/assets/stylesheets create vendor/assets/stylesheets/.gitkeep create vendor/plugins create vendor/plugins/.gitkeep
$ rm public/index.html $ echo "/vendor/bundle" >> .gitignore $ echo "/config/database.yml" >> .gitignore # .bundle/config が作成されているので --path はもう不要 $ bundle install
Fetching gem metadata from https://rubygems.org/......... Using rake (0.9.2.2) Using i18n (0.6.0) Using multi_json (1.3.5) Using activesupport (3.2.3) Using builder (3.0.0) Using activemodel (3.2.3) Using erubis (2.7.0) Using journey (1.0.3) Using rack (1.4.1) Using rack-cache (1.2) Using rack-test (0.6.1) Using hike (1.2.1) Using tilt (1.3.3) Using sprockets (2.1.3) Using actionpack (3.2.3) Using mime-types (1.18) Using polyglot (0.3.3) Using treetop (1.4.10) Using mail (2.4.4) Using actionmailer (3.2.3) Using arel (3.0.2) Using tzinfo (0.3.33) Using activerecord (3.2.3) Using activeresource (3.2.3) Using bundler (1.1.3) Installing coffee-script-source (1.3.2) Installing execjs (1.3.2) Installing coffee-script (2.2.0) Using rack-ssl (1.3.2) Using json (1.7.3) Using rdoc (3.12) Using thor (0.14.6) Using railties (3.2.3) Installing coffee-rails (3.2.2) Installing jquery-rails (2.0.2) Installing pg (0.13.2) with native extensions Using rails (3.2.3) Installing sass (3.1.18) Installing sass-rails (3.2.5) Installing uglifier (1.2.4) Your bundle is complete! It was installed into ./vendor/bundle
$ git init $ git add . # 確認 $ git status
# On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached ..." to unstage) # # new file: .gitignore # new file: Gemfile # new file: Gemfile.lock # new file: README.rdoc # new file: Rakefile # new file: app/assets/images/rails.png # new file: app/assets/javascripts/application.js # new file: app/assets/stylesheets/application.css # new file: app/controllers/application_controller.rb # new file: app/helpers/application_helper.rb # new file: app/mailers/.gitkeep # new file: app/models/.gitkeep # new file: app/views/layouts/application.html.erb # new file: config.ru # new file: config/application.rb # new file: config/boot.rb # new file: config/environment.rb # new file: config/environments/development.rb # new file: config/environments/production.rb # new file: config/environments/test.rb # new file: config/initializers/backtrace_silencers.rb # new file: config/initializers/inflections.rb # new file: config/initializers/mime_types.rb # new file: config/initializers/secret_token.rb # new file: config/initializers/session_store.rb # new file: config/initializers/wrap_parameters.rb # new file: config/locales/en.yml # new file: config/routes.rb # new file: db/seeds.rb # new file: doc/README_FOR_APP # new file: lib/assets/.gitkeep # new file: lib/tasks/.gitkeep # new file: log/.gitkeep # new file: public/404.html # new file: public/422.html # new file: public/500.html # new file: public/favicon.ico # new file: public/robots.txt # new file: script/rails # new file: vendor/assets/javascripts/.gitkeep # new file: vendor/assets/stylesheets/.gitkeep # new file: vendor/plugins/.gitkeep #
$ git commit -m "initial commit"
[master (root-commit) 230f0d4] initial commit 33 files changed, 920 insertions(+) create mode 100644 .gitignore create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 README.rdoc create mode 100644 Rakefile create mode 100644 app/assets/images/rails.png create mode 100644 app/assets/javascripts/application.js create mode 100644 app/assets/stylesheets/application.css create mode 100644 app/controllers/application_controller.rb create mode 100644 app/helpers/application_helper.rb create mode 100644 app/mailers/.gitkeep create mode 100644 app/models/.gitkeep create mode 100644 app/views/layouts/application.html.erb create mode 100644 config.ru create mode 100644 config/application.rb create mode 100644 config/boot.rb create mode 100644 config/environment.rb create mode 100644 config/environments/development.rb create mode 100644 config/environments/production.rb create mode 100644 config/environments/test.rb create mode 100644 config/initializers/backtrace_silencers.rb create mode 100644 config/initializers/inflections.rb create mode 100644 config/initializers/mime_types.rb create mode 100644 config/initializers/secret_token.rb create mode 100644 config/initializers/session_store.rb create mode 100644 config/initializers/wrap_parameters.rb create mode 100644 config/locales/en.yml create mode 100644 config/routes.rb create mode 100644 db/seeds.rb create mode 100644 doc/README_FOR_APP create mode 100644 lib/assets/.gitkeep create mode 100644 lib/tasks/.gitkeep create mode 100644 log/.gitkeep create mode 100644 public/404.html create mode 100644 public/422.html create mode 100644 public/500.html create mode 100644 public/favicon.ico create mode 100644 public/robots.txt create mode 100755 script/rails create mode 100644 vendor/assets/javascripts/.gitkeep create mode 100644 vendor/assets/stylesheets/.gitkeep create mode 100644 vendor/plugins/.gitkeep
bundle exec rails new . と現在のディレクトリ名から rails new できるのがとてもありがたい。
これが引数ベースじゃないからこそ、bundler が生きるんじゃなかろうか

Redmine を 1.4.1 から 2.0.0 にアップデートした

Redmine 2.0.0 リリース | Redmine.JP Blog
先日 1.4.x がリリースされたのに、2.0.0 が早くもリリースされました。
bundler 使っていれば、Rails のバージョンは実運用にはあまり関係ないかと思うけど、まだインストールして間もないことだしせっかくなので最新環境に変更します。
基本的に アップグレード | Redmine.JP のままやるだけだけど。
# ダウンロード→展開→配置
$ wget http://rubyforge.org/frs/download.php/76134/redmine-2.0.0.tar.gz
$ tar xvf redmine-2.0.0.tar.gz
$ mv redmine-2.0.0 /var/lib/rails/
$ cd /var/lib/rails/redmin-2.0.0

# 依存 gem をインストール
$ bundle install --path vendor/bundle --without development test mysql sqlite

# 設定ファイルを引き継ぎ
$ cp ../redmine/config/database.yml config/
$ cp ../redmine/config/configuration.yml config/

# トークンを生成。generate_session_store から generate_secret_token に変更になったらしい
$ bundle exec rake generate_secret_token

# マイグレーションを実行、追加されたのはテーブル 1 つだけだった
$ bundle exec rake db:migrate RAILS_ENV=production

# 環境を掃除して
$ bundle exec rake tmp:cache:clear
$ bundle exec rake tmp:sessions:clear

# オーナーを変更
$ chown -R www-data:www-data .

# Apache の設定ファイルを修正して再起動
$ vi /etc/apache2/site-available/redmine
<VirtualHost *:80> ServerName xxx.mkt-sys.jp - DocumentRoot /var/lib/rails/redmine/public + DocumentRoot /var/lib/rails/redmine-2.0.0/public PassengerEnabled on </VirtualHost>
$ service apache2 restart # ログローテートの設定も修正 $ vi /etc/logrotate.d/redmine
- /var/lib/rails/redmine/log/*log { + /var/lib/rails/redmine-2.0.0/log/*log { weekly missingok notifempty copytruncate }
アクセスして、ログイン→管理→情報でバージョンを確認。
バッチリですね。

XCData を後から追加するには

<name><![CDATA[pinzolo]]></name>
こんな XML を出力したい場合、通常ならばこう書けばいい。
var nameElement= new XElement("name", new XCData(obj.Name));
でも、obj.Name が null の場合、ArgumentNullException が発生する。
そこで、文字列が存在する場合のみ CDATA セクションを追加するようにしたい。
最初はこう書いた。
var nameElement = new XElement("name");
if (obj.Name != null)
{
    nameElement.SetValue(new XCData(obj.Name));
}
しかし、XObject を値にすることはできないという ArgumentException が発生した。
とりあえず次はこうしてみた。
var nameElement = new XElement("name");
if (obj.Name != null)
{
    nameElement.SetValue(new XCData(obj.Name).ToString());
}
こうなった。まあ、当たり前だ。
<name>&lt;![CDATA[pinzolo]]&gt;</name>
他にも正解はあるだろうが、とりあえず正解の一つはこれのようだ。
var nameElement = new XElement("name");
if (obj.Name != null)
{
    nameElement.ReplaceNodes(new XCData(obj.Name));
}
なるほど、置き換えてやるのね。

2012/05/14

rbenv で rubygem をインストールしても command not found となる場合

rails の開発環境をぼちぼちと整えようと思って、とりあえずグローバルな gem として pry と bundler だけインストールした。
ところが、pry はターミナルから使用できるが、bundle コマンドは command not found となった。
rbenv をインストールしていると、$HOME/.rbenv/shims と $HOME/.rbenv/bin に PATH が通っているはずなので、$HOME/.rbenv/shims を覗いてみた。
$ ll $HOME/.rbenv/shims
drwxrwxr-x 2 pinzolo pinzolo 4096  5月 14 07:52 .
drwxr-xr-x 9 pinzolo pinzolo 4096  5月 11 11:46 ..
-rwxrwxr-x 2 pinzolo pinzolo  100  5月 14 07:18 coderay
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 erb
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 gem
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 irb
-rwxrwxr-x 2 pinzolo pinzolo  100  5月 14 07:18 pry
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 rake
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 rdoc
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 ri
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 ruby
-rwxrwxr-x 8 pinzolo pinzolo  100  5月 11 11:46 testrb
こんな風になってた。全て同じサイズ??ということで diff を取ってみると、ファイル名以外は全て同じらしい。
$ cat shims/pry
#!/usr/bin/env bash
set -e
export RBENV_ROOT="/home/pinzolo/.rbenv"
exec rbenv exec "${0##*/}" "$@"
環境変数を設定して、rbenv 経由で処理を実行しているのね。
というわけで、bundle という名前でファイルをコピーしてやれば良さそうだ。
$ cp $HOME/.rbenv/shims/{pry,bundle}
$ bundle
Could not locate Gemfile
# 2012-05-15 追記
単に rehash していなかっただけだった
rbenv rehash しても command not found になるなら、お試し下さい。

2012/05/12

Ubuntu 12.04 に色々とアプリケーションをインストールした

Ubuntu 12.04 にいつもの環境を整えた。

環境系

# 日本語ディレクトリを英語に
$ LANG=C xdg-user-dirs-gtk-update

# aptitude はデフォルトではインストールされていない
$ sudo apt-get aptitude

# システムをアップデート
$ sudo aptitude update
$ sudo aptitude full-upgrade

# screen も入ってなかった
$ sudo aptitude install -y screen

# 日本語入力はmozc
$ sudo aptitude install -y ibus-mozc

# 日本語のほうがありがたい
$ sudo aptitude install -y manpages-ja

# シェルは zsh
$ sudo aptitude install -y zsh

# vim 必須
$ sudo aptitude install -y vim-nox vim-gnome

# lv 使う
$ sudo aptitude install -y lv

アプリケーション

# Google Chrome と Dropbox は本家からインストールする

# コマンドラインランチャ。これがあれば左側のいらない
$ sudo aptitude install -y gnome-do

# F12でターミナルが降りてくる。とても便利。zsh を使う際、bash をかませる必要がなくなった
$ sudo aptitude install -y guake

開発環境

# 開発するならこれは必須
$ sudo aptitude install -y build-essential

# webサーバは無難にapache
$ sudo aptitude install -y apache2

# DB は PostgreSQL(バージョンが9.1.3になってる)
$ sudo aptitude install -y postgresql libpq-dev pgadmin3

# Subversion から git に完全移行中なのであえて Subversion は入れない
$ sudo aptitude install -y git-core

# ライブラリのインストール(zlib1g-dev とか libssl-dev はすでに入ってたけど一応)
$ sudo aptitude install -y zlib1g-dev libssl-dev libreadline-dev libxslt-dev libxml2-dev libyaml-dev libsqlite3-dev

# rbenv を github から取得
$ mkdir ~/git_repos
$ cd ~/git_repos
$ git clone git://github.com/sstephenson/rbenv.git
$ cd ~
$ ln -s git_repos/rbenv .rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> .zshrc
$ echo 'eval "$(rbenv init -)"' >> .zshrc
$ source .zshrc

# ruby-build を github から取得
$ cd git_repos
$ git clone git://github.com/sstephenson/ruby-build.git
$ cd ruby-build
$ sudo sh install.sh

# 最新バージョンを確認して、最新をインストールして、使用するように設定する
$ rbenv install
$ rbenv install 1.9.3-p194
$ rbenv rehash
$ rbenv global 1.9.3-p194
Ruby on Rails 3.2 を Ubuntu にインストールする手順をかなり丁寧に説明してみました - Rails 雑感 - Ruby on Rails with OIAXとかを参照すると rbenv は apt で入れられるようになったみたいだが、自分の環境だとダメだった。
インストールはできるが、rbenv global しても /usr/bin/ruby が居座り続ける。
apt から rbenv をインストールすると ruby1.9.1(実体はruby1.9.3-p0)もインストールされる。
これが /usr/bin/ruby の実体になるので、rbenv global してから ruby -v すると、ruby1.9.3-p0 のまま。
ruby1.9.1 パッケージを削除しようとすると rbenv が依存しているため rbenv が動かなくなる。
どうにもならないので、全部削除して rbenv を github から取ってきたらうまくいった。

2012/05/11

Ubuntu 12.04 に行ったキーボード関連の設定

Ubuntu 12.04 をインストールしてまずキーボード関連の設定を行った。

CapslockをCtrlに

右上から[システム設定]を選択
[ユーザー向け]→[キーボードレイアウト]を選択
オプションをクリック
[Caps Lock キーの動作]を展開
[デフォルト]から[Caps Lock を追加の Control にするが・・・]に変更

ibus-mozcをインストール

# aptitude はデフォルトでは入ってなかった
$ sudo apt-get install -y aptitude

# aptitude で update
$ sudo aptitude update

# ibus-mozc をインストール
$ sudo aptitude install -y ibus-mozc

日本語設定

Dashをibusで検索。キーボード・インプットメソッドを立ち上げる
[一般]タブの[キーボードショートカット]→[切り替え]から余計なものを削除しAlt+graveだけにする。
削除は右の[...]ボタンからどうぞ。
[インプットメソッド]タブを表示
Mozcだけ使用するように設定

ところが...

Alt+grave しても日本語が入力できない。
Alt+Tab のようなウィンドウ選択になる。
どうやら既に Alt+grave がなにかのショートカットになっているみたい。
ぐぐってみると Gnome3における日本語入力設定 - サトルサトラレ in Boston に解決策があった。
また右上から[システム設定]を立ち上げて、今度は[ハードウェア]→[キーボード]を選択
[ショートカット]タブを表示して、左側のリストから[ナビゲーション]を選択。
どうやらこれの[ひとつのアプリケーション内のウィンドウを切り替える]が Alt+grave になっているらしい。
見た目は無効だけど、割り当てられているらしい。
これに適当に別のショートカットを割り当てる。
割り当てるには選択して割り当てたいショートカットを押せばOK。
さらに Back Space で再度無効にする
これで無事 Alt+grave で日本語が入力できるようになった。
こんなん完璧にトラップじゃねーか!

VMWare Player に Ubuntu 12.04 をインストールした

Ubuntu 12.04 LTS Desktop 日本語 Remix CD がリリースされていたので、開発環境を構築するために VMWare Player にインストールした。

CDイメージのダウンロード

Ubuntuの日本語環境 | Ubuntu Japanese Team から iso ファイルをダウンロード。
32bitしかないのね、まあいいか。

VMWare Playerで仮想マシンの作成

通常のインストールと同様にするため、OSは後からインストールする。
ゲストOSはLinux、バージョンはもちろんUbuntu
仮想マシンの名前と置き場を指定。データ置き場が E ドライブなので、デフォルトから変更した。
長く使う予定なのでファイルのサイズを100G、移動とか後の管理がしやすいのでファイルは分割する。
後からでもできるけど、この段階でカスタマイズする。
メモリは4G。Ubuntu 12.04はデフォルトでPAEが有効になっているから3G以上指定しても無駄にならないよ。
プロセッサはとりあえず2つ使う。本格的に開発するようになったら4にするかも。
仮想マシンを再生したら自動的にインストールが始まるように、ISOイメージファイルをダウンロードしたISOファイルに指定しておく。
作成完了。仮想マシンを再生したらインストール始まります。

Ubuntu 12.04 のインストール

新規作成のVMで試すのは時間の無駄かなということでいきなりインストール。
「インストール中にアップデートをダウンロードする」と「サードパーティのソフトウェアをインストールする」にチェックして続ける。
専用領域なんだしおまかせで。
ドライブを選択。一つしかないけどね。
インストール始まりました。
地域を選択。最初から Tokyo になっているので問題なし。
ちなみに下に表示されているファイルのコピーはバックグラウンドで別スレッドで動いてる。
キーボードのレイアウトを選択。デフォルトでは日本語キーボードになっているけど、自分が使用しているのは英語キーボードなので、英語(US)を選択。
自分のユーザーを作成。名前・マシン名・ユーザー名・パスワードを入力。
自動的にログインはしない。毎回パスワード入力するほうがセキュリティ的に安心できる。
残りのインストールが始まる。
インストールが完了した、簡単だね。再起動します。
ログイン画面が表示された。後はログインして好きなように使いましょう

感想

  • インストールは相変わらず簡単。基本的にポチポチしてれば大丈夫
  • フォントとか画面描画とか綺麗になってる
  • VMWare でもデスクトップ効果が有効になったのか、guakeの透過が可能になってたり、gnome-doのスキンが変更できたり実機へのインストールと見た目も変わらん
  • メニューが大幅に変わったので慣れるまで使いにくいかも、最初の環境設定がやりにくくてしゃーない
  • Dashは便利。というか最初はDashか右上のシステム設定でなんとかするしかない
  • アプリの一覧とかアクセスしにくくなった。カテゴリで絞り込むのも手間かかる。まあgnome-doあるので問題ないけど
  • より一般ユーザー向けになった印象

2012/05/10

C#にて空のシーケンスを返すには

今の C# って List よりも IEnumerable 中心のコーディングだから、null じゃなく空のシーケンスで IEnumerable を初期化したい場合がある。
そんな場合は、Enumerable.Empty を使えばいいみたいだ。
var values = Enumerable.Empty<String>();

IEnumerable.ConvertAll を作ろうかと思ったら

ConvertAll って便利ですよね。
var numbers = new List<int>() { 1, 2, 3, 4, 5 };
numbers.ConvertAll<String>(n => n.ToString() + n.ToString()).ForEach(Console.WriteLine);
結果は↓
11
22
33
44
55
でも、これはListのメソッドなので IEnumerable だと、ToList をかましてからでないと利用できない。
仕方ないので拡張メソッド書くかと思って、みんなどうしてるのか調べてみたら Select で同じ事できたのね。
IEnumerable<int> numbers = new List<int>() { 1, 2, 3, 4, 5 };
// IEnumerable<T>.ForEach は実装済み
numbers.Select<int, String>(n => n.ToString() + n.ToString()).ForEach(Console.WriteLine);

2012/05/01

Visual C# 2010 Express に NUnit を使用する

ダウンロードとインストール

NUnit - Download から msi をダウンロード(現時点で最新は NUnit-2.6.0.12051.msi)。
インストールはおなじみ、ダブルクリックしてぽちぽちぽちっと

Visual Studio に登録

[ツール]→外部ツールメニューにて下記のデータでエントリを追加。
  • タイトル : NUnit
  • コマンド : C:\Program Files\NUnit 2.6\bin\nunit.exe
  • 引数 : /run $(ProjectDir)/$(ProjectFileName)
  • 初期ディレクトリ : $(ProjectDir)
これで、ツールメニューに外部ツールとして NUnit が登録される。

Debug ビルドを可能に

デフォルトだと強制的に Release ビルドになるので、Release と Debug を選択できるようにする。
  1. [ツール]→[設定]にて基本設定から上級者設定に変更。これでソリューション構成選択などのメニューが上部に現れる。
  2. [ツール]→[オプション]のダイアログにて、左下の「すべての設定を表示」にチェック
  3. [プロジェクトおよびソリューション]→[全般]メニューにて「ビルド構成の詳細を表示」にチェック
これで、選択した構成でのビルドが可能になる。

試してみる

サンプルプロジェクト(NUnitSample) を作成、Class1 を Sample クラスに変更して、SampleMethod メソッドを登録。
using System;

namespace NUnitSample
{
    public class Sample
    {
        public int SampleMethod(string text)
        {
            return 0;
        }
    }
}
テスト用プロジェクト(NUnitSampleTest)を追加し、参照設定にプロジェクトから NUnitSample プロジェクトを、.NET から nunit.framework を追加。 テストクラス SampleTest を作成し、テストメソッドを追加。
using System;

using NUnit.Framework;
using NUnitSample;

namespace NUnitSampleTest
{
    public class SampleTest
    {
        private Sample sample = new Sample();

        [Test(Description="引数 null 時のSampleMethodテスト")]
        [ExpectedException(typeof(ArgumentNullException))]
        public void SampleMethodWithNullArgument()
        {
            this.sample.SampleMethod(null);
        }

        [Test(Description="数値でない引数のテスト")]
        [ExpectedException(typeof(ArgumentException))]
        public void SampleMethodWithInvalidArgument()
        {
            this.sample.SampleMethod("hoge");
        }

        [Test(Description="正常な引数時のテスト")]
        public void SamplemethodWithValidArgument()
        {
            int expected = 1234;
            int actual = this.sample.SampleMethod("1234");
            Assert.AreEqual(expected, actual);
        }
    }
}
[外部ツール]→[NUnit]で実行する。
当然失敗する。
ソースコードを修正する。
using System;

namespace NUnitSample
{
    public class Sample
    {
        public int SampleMethod(string text)
        {
            if (text == null)
            {
                throw new ArgumentNullException("text");
            }
            int result = 0;
            if (Int32.TryParse(text, out result))
            {
                return result;
            }
            else
            {
                throw new ArgumentException("text");
            }
        }
    }
}
実行して成功するのを確認する。