使っているフリーウェア・シェアウェア
順不同で上げてみます。
秀丸エディター・秀丸パブリッシャー・Hidemarnet Explorer(旧 秀丸エクスプローラー)
http://hide.maruo.co.jp/software/hidemaru.html
言わずと知れた国産エディター。主にHTML、SQL、メモ書きに使用しています。
SQLを実行するマクロ*1を自作したりして、かなり使い勝手をカスタムしています。
秀丸ファイラーClassic
http://hide.maruo.co.jp/software/hmfilerclassic.html
タブファイラー。タブの分割、別ウィンドウへの切り離し、統合とかなり柔軟。
マウスジェスチャも使えて便利。また、独自に「お気に入り」を管理でき、ツールバーに登録できる。
同じようなタブファイラーにMDIE(http://cres.s28.xrea.com/soft/mdie.html)があって、つい先週の木曜日まで使っていたのだけれども、@civicさんが
http://twitter.com/#!/civic/status/119635444332888064:twitter
とつぶやいてたのを見て試してみたところ、そっこーで乗り換え決定。
秀Caps
http://hide.maruo.co.jp/software/hidecaps.html
MS-DOS時代、PC-98でATOKを使っていた癖が抜けないため、「変換」キーでIMEのON/OFFをするために使っています。
ZTop
http://www15.plala.or.jp/then/ztop/index.html
マウスのホイール補助機能として使っています。フォーカスが当たっていないウィンドウでもホイールが利くのが便利。
SQLFix
http://www.vector.co.jp/soft/win95/business/se266921.html
SQL整形ツール。整形ルールも指定できるし、クリップボードに対象SQLをコピーして実行するだけという手軽さが気に入っています。
All CPU Meter
http://addgadget.com/all_cpu_meter/
Windows Vista、7のデスクトップガジェットとして動作するCPUメーター。かっちょいいので気にいってます。
Foxit J-Reader
http://www.foxitsoftware.com/japan/products/reader/reader.php
高速PDFビューワー。普段はこちらで。ただ、日本語フォントのきれいさは、Adobe Readerの方が上という印象。
BullZip PDF Printer
プリンタとして組み込まれ、印刷するとPDFを作ってくれる。
PrimoPDFを以前使っていたけど、こちらの方が日本語ファイルとかへの対応がよいので乗り換え。
Lhaz
http://www.chitora.jp/lhaz.html
7-Zipや、tar.gz等にも対応していて便利なので愛用。
ただ、コンテキストメニューから選んだら、別のコンテキストメニューが立ち上がるのだけはいただけない。
あとは開発に使用するものとして、GitとかTortoiseSVNとはMercurialとか入れてるけど、割愛。
こうやって見ると、結構たくさん使ってるものですね。
一つ上の視点を持つ - 新卒準備カレンダー2011春 #newgrad2011 - by @masaru_b_cl
※写真はFlickrから拝借しました。
「新卒準備カレンダー 2011春 : ATND」の26日目として、寄稿させていただきます。
(ひとつ前は@kenji_rikitakeさんの並行な混沌: 挫折の先に見えたものです。)
ところであなたは?
2003年春に新潟県長岡市にある中小システムインテグレーターに新卒として就職した、いわゆるシステムエンジニアです。設計から実際にプログラミング、さらにシステム管理のようなこともやっています。
個人的に一番力を入れているのは.NET界隈で、主にC#をメインに使っています。ただ、仕事ではJava、SQL、VB、etc...と、そのプロジェクトごとに毎回違うプラットフォームでの開発となります。
仕事以外の活動としては、まずはblog「http://blogs.wankuma.com/masaru/」での情報発信、「長岡 IT開発者 勉強会(NDS)」でのセッションスピーカー、書籍執筆(かんたんASP.NET (プログラミングの教科書))などを行っています。
そして、家に帰れば、3歳になる息子の子育てに苦労する毎日を送っています。
今回伝えたいこと
私がみなさんに伝えたいことは「一つ上の視点を持つ」ことの大事さです。
みなさんが新人として仕事をするとき、まずは全体から見ればごく一部分の何らかの「作業」を担当することになると思います。たとえば、詳細設計書を渡され一つの機能のプログラミングを行ったり、何らかのドキュメント作成を指示されたりといったことです。
与えられた仕事は、先輩社員達のようなある程度経験がある人間にとっては簡単なことかもしれません。しかし、おそらくみなさんにとってはかなり苦労することもあるでしょう。そして、次から次へと作業が降ってくるはずです。そんな時はどうしても作業に忙殺され、余裕がなくなってしまいます。
でも、そんな中だからこそ「一つ上の視点」を持ってもらいたいのです。「一つ上の視点」とは、目の前のことではなく、自分の置かれた状況を「俯瞰して」見ることです。
たとえば、次のようなものです。
- ひたすら降ってくる作業をこなす
→自分がいまどのような作業をどのくらい抱えているのか考える - 設計書通りに作る
→なぜそのような設計になっているのか考える - 指示された作業を指示通りに行う
→その作業にどんな目的があるのか考える
このように視点を変えることで、目の前のことだけ見ていた時とは違うことに気付けるようになります。
- 作業の優先度をつけて効率的にこなせるようになる、自分の能力を明らかに超えた作業を断りやすくなる
- 設計上の不具合に気付きやすくなる
- 目的から外れたあさっての方向を向いた作業を行うことがなくなる
「一つ上の視点」に慣れてきたら「二つ上」、「三つ上」とどんどん視点を上げていくのもよいでしょう。具体的には次のような感じです。
視点 | 例 |
---|---|
↑ | 自分の目標 |
| | 会社の目標 |
| | 部署の目標 |
| | プロジェクトの目標 |
| | 作成するシステムの目的 |
| | 担当機能が属するサブシステムの目的 |
| | 担当機能の設計の目的 |
| | 担当機能の設計 |
↓ | 担当機能の実装方法 |
このように、それぞれの視点で自分のやるべきことを考える癖をつけておきましょう。
「一つ上の視点」を得るためには
とはいえ、いきなり「一つ上の視点」を持てと言われても、どう考えたらよいかわからないですよね。そこで「一つ上の視点」を得るためにどのようなことをしたらよいか、私の経験で恐縮ですが紹介しようと思います。
何よりもまずは現状把握
建物を作るにしても、土台がしっかりしていなくては上に立つ建物は決して頑丈とは言えません。それと同じで、まずは土台となる「目の前のこと」について、それぞれが今どのような状態で、何をいつまでにしなければならないか、などを整理しましょう。目の前のことが把握できると、それだけで「一つ上の視点」で考えやすくなります。
なお、整理する方法は何でもいいのですが、個人的にはGTDの手法をお勧めします*1。
本やWebの記事などを読む
「視点」を変えるためには、必要な知識を持っていることも重要です。プログラミングの手法に関する本、設計に関する本、マネジメントに関する本、会計に関する本、経済に関する本、etc...とあらゆる方面の本やWebの記事を読みましょう。全く関係がないと思える分野の本を読んでいて、思いがけず参考になる記載を見つけることもままあります。
先輩、上司の考えを知る、考える
先輩、上司は皆さんが働く環境での「一つ上の視点」を持っている、一番身近な存在です。まずはそういう意人たちから「一つ上の視点」での考えを聞いてみましょう。おそらくは、みなさんが想像しやすい範囲での経験や考えを教えてくれるはずです。
そしてその後は、もし自分がその人たちの立場だったらどう考えるかイメージしてみましょう。
まとめ
- 目の前の作業に忙殺されず、常に「一つ上の視点」を意識しよう
- 一つ上の視点を持つには、まず土台となる「目の前のこと」をしっかりと把握しよう
- そのうえで、本やWebサイト、先輩社員の経験談、考え方などを学び、徐々に視野を広げていこう
おすすめの書籍、Webサイト
- 作者: デビッド・アレン,田口元
- 出版社/メーカー: 二見書房
- 発売日: 2008/12/24
- メディア: 単行本(ソフトカバー)
- 購入: 127人 クリック: 1,493回
- この商品を含むブログ (302件) を見る
- 作者: Joel Spolsky,青木靖
- 出版社/メーカー: オーム社
- 発売日: 2005/12/01
- メディア: 単行本
- 購入: 18人 クリック: 371回
- この商品を含むブログ (451件) を見る
- 作者: Joel Spolsky,青木靖
- 出版社/メーカー: 翔泳社
- 発売日: 2009/04/09
- メディア: 単行本(ソフトカバー)
- 購入: 12人 クリック: 166回
- この商品を含むブログ (94件) を見る
- 作者: 森博嗣
- 出版社/メーカー: 集英社
- 発売日: 2009/11/17
- メディア: 新書
- 購入: 28人 クリック: 1,154回
- この商品を含むブログ (135件) を見る
*1:「すべてのこと」を一連の流れで収集、管理するための手法。詳しくは紹介する書籍を参照。
「Application Architecture Guide 2.0 日本語訳」が全章公開された!
http://www.microsoft.com/japan/msdn/vstudio/2010/solutions/architecture/
ただ、全章完全版PDFの以下の点が残念。
- 「しおり」がついていない。
- 目次から各章にジャンプできない。
Microsoft方面の方々、何とかしていただけないでしょうか?
VBプログラマが知るべき9のこと by @masaru_b_cl
インスパイアードバイ:Javaプログラマが知るべき9のこと - @katzchang.contexts
最初はC#について書こうと思ったんだけど、大体一緒になっちゃうから、VBにしてみた。
なお、この記事に書いてあることは目新しいことでもなんでもなく、これまで各所でいろいろといわれていたことをまとめたものです。
Option Strict を On に
まず真っ先にしてほしいのが、「Option Strict」を「On」にすることである。
Option Strict ステートメント (Visual Basic) | Microsoft Docs
暗黙的なデータ型変換を拡大変換だけに制限します。
Option Strictは明示的にOnにしないと、既定ではOffとみなされるため、次のようなコードが書けてしまう。
Dim str As String str = 100
上記のコードでは変数の宣言と値の設定が近い位置にあるため、文字列を扱っていることがすぐにわかるが、実際現場で目にするような長大なコード*1では、その変数が文字列を扱うのか数値を扱うのか即座に判別することができないため、保守が苦痛になる。
また、次のようなコードも書けてしまう。
Dim str As String str = "12" + 34 Console.WriteLine(str) // ここの結果は?
Console.WriteLineでコンソールにどんな値が表示されるか、すぐにわかるであろうか?*2
Option StrictをOnにすることで、上記のようなコードは全てコンパイルエラーとなる。
では、どうやってOption Strictを設定するかというと、私はVisual Studioのオプションで、[Visual Basicの既定値]を変更してしまうことを勧める。
On Errorは使わない
VB6時代のエラーハンドリング用構文である「On Error 〜」は現在のVBでも使用できる。
On Error ステートメント (Visual Basic) | Microsoft Docs
エラー処理ルーチンを有効にして、プロシージャ内でルーチンの場所を指定します。また、エラー処理ルーチンを無効にする場合にも使用できます。
On Error ステートメントを使用しないと、発生するすべてのランタイム エラーが致命的なエラーになります。つまり、エラー メッセージが表示され、実行が停止します。
Sub Main() On Error GoTo ErrorHandler ' 何かエラーが発生する処理 DoRaiseErrorProcedure() Exit Sub ErrorHandler: ' エラー処理 End Sub
だが、On Errorはあくまで「プロシージャ単位」でしかエラーのハンドリングが出来ない上、特定のエラーだけハンドリングするといったこともできない。VB6時代のソースをほとんど流用するといった特殊な場合でない限り、構造化例外処理を使用すべきである。
Visual Basic での構造化例外処理 | Microsoft Docs
以下に構造化例外処理を使った例を示す。
Public Sub Main() Try ' 何かエラーが発生する処理 DoRaiseErrorProcedure() Catch e As Exception ' エラー処理 Finally ' 共通後処理 End Try End Sub
構造化例外処理では、Finallyを使用して共通の後処理が行えることも大きな特徴である。
ただし、構造化例外処理もプロシージャ単位で行っていてはOn Errorとほとんど変わらない。プロシージャでは原則として例外のCatchは行わず、「集約例外ハンドラ」で行うようにし、後処理が必要なものは、Finallyで行うことを勧める。
以下にコンソールアプリケーションにて集約例外ハンドラを用いた例外処理の例を示す。
Sub Main() Public Sub Main() AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException Try ' 何かエラーが発生する処理 DoRaiseErrorProcedure() Finally ' 共通後処理 End Try End Sub ' 集約例外ハンドラ Private Sub CurrentDomain_UnhandledException(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs) Console.WriteLine("致命的なエラーが発生しました。") Environment.Exit(-1) End Sub
なお、.NET言語の例外処理については、以下のエントリが詳しいのでぜひ一読して欲しい(コードはC#だが意味は通じるはず)。*3
.NETの例外処理 Part.1 – とあるコンサルタントのつぶやき
.NETの例外処理 Part.2 – とあるコンサルタントのつぶやき
.NETの例外処理 Part. 3 – とあるコンサルタントのつぶやき
.NET の例外処理 Part. 4 – とあるコンサルタントのつぶやき
Form.Show()はしない
Windowsアプリケーションにて他のWindowを開きたい場合、通常は以下のように記述する。
Dim subForm As New SubForm() subForm.Show()
しかし、VBは次のような記述も出来てしまう。
SubForm.Show()
では、なぜVBではコンパイルエラーとならず、しかも動作してしまうのか?それは「Formの既定のインスタンス」と呼ばれる機能が関係している。この機能は、Visual StudioでWindows Formアプリケーションを作成する際、「プロジェクトに含まれるFormクラス」を自動的にインスタンス化し、My.Formsオブジェクトのプロパティとして公開するものだ。
My.Forms オブジェクト (Visual Basic) | Microsoft Docs
現在のプロジェクト内で宣言されている各 Windows フォームのインスタンスにアクセスするためのプロパティを提供します。
つまり、上記のコードは、SubFormクラスの静的なShowメソッドではなく、My.FormsオブジェクトのSubFormプロパティを通じて、SubFormクラスのインスタンスを取得して、そのShowメソッドを呼び出していることになる。
この機能はVB6時代と同じ書き方が出来るように導入されたものと推測するが、Formのインスタンスが「どこ」に属するのかを意識しないため、予期せぬバグを生みやすい。よって、Formは明示的にインスタンス化してShowメソッドを呼ぶようにしたほうが良い。
なお、「Formの既定のインスタンス」を抑止する方法もあるようである。詳しくは以下のエントリをコメントまで含めて参照していただきたい。
VB2005 で「Form の既定のインスタンス」と My の使用を防ぐには?
ByVal,ByRefを明示する
VBはプロシージャの引数に対して、ByVal(値渡し)、ByRef(参照渡し)を指定することができる。
引数の値渡しと参照渡し (Visual Basic) | Microsoft Docs
例を挙げると次のようになる。
Private Sub Hoge(ByVal a As Integer, ByRef b As Integer) a = 2 b = 2 End Sub Sub Main() Dim a As Integer = 1 Dim b As Integer = 1 Hoge(a, b) Console.WriteLine("{0},{1}", a, b) ' 結果:1,2 End Sub
ByValを指定した引数に値を設定しても、呼び出し元の変数の値は変わらないが、ByRefを指定した場合、呼び出し元の変数の値が書き換わる。
この、ByVal、ByRefを省略するとどうなるかというと、既定でByValとして扱われる。*4
しかし、一見してどちらの動きとなるかわかりづらいため、ByVal、ByRefは省略せずに書くべきである。
なお、ByVal、ByRefについて、より詳しく知りたい場合は、以下の記事が参考になる。
連載:プロフェッショナルVB.NETプログラミング 第11回 プロシージャとプロシージャ引数(1/3) - @IT
文字列連結は&で行う
VBで文字列を連結するには、「+演算子」か「&演算子」を使う。
Visual Basic の連結演算子 | Microsoft Docs
Dim a As String = "1" + "2" Dim b As String = "1" & "2"
ただ、「+演算子」は数値演算でも使用するため紛らわしい。特に「Option Strict Off」と組み合わさると凶悪さを増すことは前述のとおり。
したがって、文字列を連結する場合、常に「&演算子」を使ってもらいたい。
なお、相当数の文字列をループで連結するような場合*5、演算子による連結ではなく、StringBuilderクラスを使用すべきであるので、併せて覚えておいてもらいたい。
StringBuilder Class (System.Text) | Microsoft Docs
連結する String オブジェクトの数が決まっている場合は、String クラスを使用した方が効率的です。 この場合、個々の連結演算は、コンパイラによって 1 つの演算に結合されます。 これに対し、ランダムな数の文字列をユーザーから入力として受け取り、ループ処理で連結する場合など、連結する文字列の数が不定である場合は、StringBuilder オブジェクトが適しています。
プロシージャ呼び出しの()は略さない
VBでプロシージャ(メソッド)を呼び出す際、引数がない場合()を省略できるが、プロパティと紛らわしいため()を省略してはいけない。
Private Function Hoge() As String ' 〜 End Function Public Sub Main() Dim hoge As String = Hoge ' プロパティ?メソッド? Dim fuga As String = Hoge() ' メソッド呼び出しだとすぐわかる End Sub
なお、Visual Studioでコードを書く場合は、自動的に()が補完される。
Callを使用しない
VBでプロシージャを呼び出す方法として、Callがある。
Call ステートメント (Visual Basic) | Microsoft Docs
Function 、Sub、またはダイナミック リンク ライブラリ (DLL) プロシージャに制御を渡すフロー制御ステートメントです。
Private Function Hoge(ByVal a As String, ByVal b As String) As String Return a & b End Function Private Sub Fuga(ByVal a As String, ByVal b As String) Console.WriteLine(a & b) End Sub Sub Main() Call Hoge("a", "b") Call Fuga("a", "b") Hoge("a", "b") Fuga("a", "b") End Sub
だが、Callは付けても付けなくても、結果は同じである。わざわざつける必要はない。*6
長大なWithは避ける
VBの特徴的な記法として、Withがある。
With...End With ステートメント (Visual Basic) | Microsoft Docs
オブジェクトや構造体への参照を繰り返し指定する、一連のステートメントを実行します。
Dim product As New Product() With product .Code = "001" .Name = "商品" End With
Withを使うことで、特定のオブジェクトのメンバへのアクセスをまとめて記述することができる。
だが、入れ子にしたり、Withの中で関係のない処理をしたり、他のステートメントと合わさると、急に凶暴性を発揮する。
Dim org As New Organization() With org .Code = "001" .Name = "○○株式会社" For Each dept As Department In .Departments With dept .Code = "001001" ' org と deptのどっちのメンバ? .Name = "ソフトウェア開発事業部" End With Next ' ' ' ' ' ' ' ' ' 〜かなりの長さの関係ない処理 ' ' ' ' ' ' ' ' ' .Level = Level.Top ' どのインスタンスのメンバ? End With
コード例に示したように、「.〜」で指定したメンバが、どのインスタンスのものか非常にわかりにくくなってしまう。*7
Withを使う場合、1画面に収まる程度の長さにし、極力入れ子にしないよう心がけていただきたい。
無意味なNothingの代入
VB6以前では、以下のように変数にNothingを代入することで、オブジェクトを破棄していた。
Set hoge = Nothing
その延長なのか、メソッドの終わりで変数にNothingを代入しているソースをよく見かける。
Sub Main() Dim product As New Product() ' 〜 処理 product = Nothing End Sub
このような記述はVB.NET以降では「意味がない」。なぜならNothingを代入してもオブジェクトは破棄されないからである。*8
また、参照型でなく値型にNothingを代入した場合、暗黙的にその型の初期値が設定される。
Nothing (Visual Basic) | Microsoft Docs
変数に Nothing を代入すると、変数の宣言された型に対する既定値が変数に設定されます。 型に変数のメンバーが含まれている場合は、すべてに既定値が設定されます。
Dim i As Integer = Nothing ' 0 Dim b As Boolean = Nothing ' False
そんな「暗黙の既定値」に頼ったコードは可読性も悪く、思わぬバグも生みかねない。したがって、まったく意味がない上に余計な混乱を招く可能性があるNothingの代入は行わないようにしてもらいたい。
なお、IDisposableインターフェースを実装した型はDisposeメソッドを呼び出すことで、明示的に「アンマネージ リソース」を解放する。
IDisposable.Dispose Method (System) | Microsoft Docs
Usingステートメントと併用して、原則的にDisposeを必ず呼ぶようにしてもらいたい。
Using ステートメント (Visual Basic) | Microsoft Docs
Using conn As new SqlConnection() ' 〜 connを使った処理 End Using ' ブロックを抜けるときに必ずconn.Disposeメソッドが呼ばれる
まとめ
VB6以前とVB.NET以降は「別の言語」。その言語にそった正しい記述を心がけよう。
*1:場合によっては数百から千行を超える。
*2:"12"が数値として扱われるため、正解は46になる。
*3:上記コードも紹介したエントリを参考にさせていただいた。
*4:VB6時代はByRefとして扱われていた。
*5:CSVフォーマットのテキストを生成する、などが考えられる。
*6:私の考え。人によってはCall付けた方が見やすいって人もいると思う。
*7:親Withのメンバには子Withの中では「.〜」ではアクセスできないけれど。
*8:オブジェクトの破棄はGC(ガベージ・コレクタ)によって自動的に行われる。ごくまれにGCに回収されやすくするためにNothingを代入することもあるが、そんなのレアケース。
一応応募
バレンタインチョコ欲しい!
欲しいプレゼントは…MacBook Air 11インチ欲しい!
って
1つあたりの購入金額が5万円(税・送料込)を超えない商品に限ります
だめじゃんorz
・・・iPod touch欲しい
Apple iPod touch 64GB MC547J/A
- 出版社/メーカー: Apple(アップル)
- 発売日: 2010/09/02
- メディア: エレクトロニクス
- 購入: 12人 クリック: 580回
- この商品を含むブログ (101件) を見る
応募するだけしてみよう
MacBook Air 11インチ欲しい!
手に入れたらあんなことやこんなことに使いたい!
持ち運べるPCほしいのよね。
Console.Writeの出力先をMemoryStreamにする
Console.Writeの結果をUnitTestするにはどうすればいいのかなー、と思ってConsole.Outを挿げ替える方法を調べてみました。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string text; using (var ms = new MemoryStream()) using (var sw = new StreamWriter(ms)) using (var tw = TextWriter.Synchronized(sw)) { sw.AutoFlush = true; // 自動でMemoryStreamにFlush Console.SetOut(tw); // 標準出力の出力Streamを挿げ替える Console.WriteLine("test"); // MemoryStreamから読み込む using (var sr = new StreamReader(ms)) { ms.Position = 0; // ポジションが末尾になっているので先頭に変更 text = sr.ReadToEnd(); } } // 標準出力の出力Streamを元に戻す using (var std = new StreamWriter(Console.OpenStandardOutput())) { std.AutoFlush = true; Console.SetOut(std); Console.Write(text); } } } }