日々の記録。

プログラミングのメモや感じた事などを記録。

C#のusingが、Java7でtry-with-resource statementとして実現

C#には、ファイルやDBのリソースのクローズを必ず行うためにusingステートメントという便利な機能があります。

void foo() {
  using (TextWriter w = File.CreateText("test.txt")) {
         w.WriteLine("ごにょごにょ");
  }
}

上記の例では、TextWriterオブジェクトは、usingのブロックが終了する時点で、自動的に閉じられます。(例外が発生しても閉じられます。)

 最近Java(JDK6)に触る機会があったのですが、DBコネクションのクローズの際にこの機能がJavaにもあれば・・・と思う事が多々ありました。 ちょっと調べたところ、JDK7にはtry-with-resource statementという機能が追加されていて、C#のusingと同等のことができるようです。

void foo(Connection con) throws SQLException {
    String query = "select ...";
    try (Statement stmt = con.createStatement()) {
      ResultSet rs = stmt.executeQuery(query);

      while (rs.next()) {
        ....
      }
    } catch (SQLException e) {
      JDBCTutorialUtilities.printSQLException(e);
    }
}

Javaを扱うこと自体めっきり減りましたが、JDK7を利用する機会があれば、積極的に使いたい機能だと思います。

お酒の量を減らすのに効果があったこと

 半年くらい前まで、仕事帰りに必ず缶チューハイを買って帰っていたのですが、とある事を試してから、(自分にとっては)あまり苦も無くお酒を買う回数が減らすことができました。

(・・・あくまでも個人的な経験なので、他の方にも効果があるかは全く保証できません。)

半年前までは・・・

 半年前の帰宅パターンは、こんな感じです。

 「仕事が終わる」
    ↓
 「電車に乗る」
    ↓
「駅前のスーパーでお酒を買う」
    ↓
  「家に着く」
    ↓
  「飲む」

 飲むことが当然となっていて、駅前のスーパーに寄るのも当たり前でした。「飲まずにやっていられるか〜」といった感じです。

お酒の量を減らそうとしたきっかけ

 飲むとやっぱり眠くなります。「飲んですぐ寝てしまう時間を、勉強や家族との時間にあてられないか?」と思い立ったのがお酒の量を減らそうと思い立ったきっかけです。

現在の行動パターン

 「仕事が終わる」
    ↓
 「電車に乗る」
    ↓
 「選択肢へ」

選択1
 「ものすごい飲みたい気分。駅前のスーパーでお酒を買う」
    ↓    
   「家」

選択2
 「ちょっと飲みたい気分。買わずにとりあえず家に帰る」
    ↓
 「それでも飲みたい」
    ↓
 「近くのコンビニに行き、お酒を買う」

選択3
 「飲まなくてもいいかな?」
    ↓
  「家」

 行動として変えた点は、多少飲みたくても家までは購入を先延ばしすることです。家について、それでも飲みたかったら買いにい行きます。家についてからお酒を買いに行くのは、ちょっとした手間です。さらに、コンビニのお酒はスーパーと違って定価で若干高いです。手間やコストを増やす事が多少抑止効果になっていると思います。(ちなみに私は、普段からお酒の買い置きはしていません。)

 意識している点としては2つあり、1つは「無理をしない」というのがあります。「飲んじゃダメだ」と思わず、駅前のスーパーについても「ちょっと飲みたいけど、まぁコンビニまで様子を見よう」とちょっとずつ買うことを先延ばしして、それでも「飲みたい気持ち」が強ければ買います。

 書いていて思ったのですが、「家」にお酒がある状態にすると、その誘惑を避けることは難しいと思います。買い置きしている場合は、「家」にお酒を置かない状態にして、「飲んでもいいけど、お酒を飲むためには多少の手間をかける」という状況を作る事が大切かもしれません。

 もう一つ、一番大切な意識付けがあります。

一番大切な意識付け

 この方法のきっかけは、一時話題(?)になった「スタンフォードの自分を変える教室」という本の中にあります。その中の「「思考」を抑えつけず「行動」だけ自制する」という内容が、このお酒の量を減らす方法の元になっています。

 本ではチョコレートでの実験が紹介されていますが、お酒の話に置き換えるなら「お酒を飲みたい」という欲求を我慢しようとすればするほど、人はお酒を飲みたくなり、結局我慢できなくなってしまうそうです。

 それではどうすれば良いかというと、「我慢するのではなく「飲みたいという気持ちを抑えずに素直に認めること。ただし、思った通り感じた通りに振る舞う必要はない。」という事を、思い出すこと」と書かれています。(本では、お酒ではなくチョコレートの例です。)

 先ほど紹介した「現在の行動パターン」の「選択する」タイミングで、この意識付けを思い出す事で、確かにお酒を買うのを先延ばしできているように思います。さらに、このタイミングでお酒を控えたいきっかけを思い出すと、「飲みたい欲求」が抑えられる気がします。

 お酒を日々買う人もいれば、買いだめする人など、色々な形で飲酒をしている方がいると思います。行動は様々ですが、この意識付けを日々の行動に取り入れる事で、お酒の量が減らせるかもしれません。

まとめ

  • 「飲みたいという気持ちを抑えずに素直に認めること。ただし、思った通り感じた通りに振る舞う必要はない。」という意識付けをする。

  • お酒を買うときに「意識付け」と「お酒を減らしたいきっかけ」を思い出し、買うことを先延ばしする。

  • 無理をしない。やっぱり飲みたければ飲む。(できれば、お酒の購入は先延ばししてみる。)

以上です。

ruby LinuxやWindowsのコマンドをクラスメソッドに割り当てるクラスマクロの例

昨日の書いた「Windows セットアップ用(環境設定用)のスクリプトがあったら便利だなぁと」の第一歩として、画面解像度を変更するスクリプトを作成してみました。

 そのついでに、楽にrubyのメソッドとコマンドを対応づけられないかと思い、クラスマクロ化したのでその方法について紹介します。ただし試作なので、値の無いオプションや、コマンドの実行結果に対する処理について対処していません。

 作成した結果としては・・・普通にメソッドを定義した方が分かりやすく十分かもしれませんが。。。

利用例

定義方法の前に、実際の利用例について紹介します。

dcという画面解像度を変更するコマンドruby化した例を示します。

dc -width=1024 -height=768 -depth=32
#ruby化した例

#ディスプレイの解像度を変更する
Display.set do |d|
 d.width=1024
 d.height=768
 d.color=32
end

行数は増えていますが、Windowsのbatで処理するよりrubyの方が楽にかける・・・はず。実行結果に対する処理とか、制御文とか・・・。

Display.setの定義

Display.setの定義は、自作したクラスマクロbind_commandを利用しています。 Displayのクラスメソッドを追加するために、ちょっと特殊な事をしています。

#coding: utf-8

# クラスマクロを定義しているモジュール
require './command_binder.rb'

class Display

  class << self
    extend CommandBinder
    # ここでメソッドsetと'dc'を関連づけている
    bind_command :set, 'dc', {
      width: "-width=",
      height: "-height=",
      color: "-depth=",
      monitor: "-monitor="
    }
  end

end

command_binder.rbの実装

bind_commandメソッド中で、define_methodを使ってメソッドを定義しています。

#coding: utf-8

require 'ostruct'

module CommandBinder

  def bind_command action_sym, command, options = nil 

    define_method(action_sym.to_s) do |*args, &block|
      params = OpenStruct.new
      block.call params if block
      
      #コマンド文字列の作成
      cmd = command.to_s
      params.marshal_dump.each do |key,value|
        real_option = options[key] if options and options.has_key? key 
        cmd << " #{real_option}#{value}"
      end 

      #コマンドの実行
      `#{cmd}`
    end 
  end 
end

Windows セットアップ用(環境設定用)のスクリプトがあったら便利だなぁと

仕事では、開発したアプリケーションを投入するだけではなく、クライアントPCなどのOSセットアップをすることが良くあります。例えば解像度を指定したり、スタイルを変更したり、パフォーマンス優先にしたり、JREをインストールしたりなどなど。

そうした一連の処理をスクリプトで記述できたら楽だなぁ、といつも思ってはいるけど、1つのプロジェクトで何度もセットアップを行うわけではないので、ついつい手作業に・・・。(無人インストールという方法もあるそうですが、試したことはありません。怠慢です。)

例えばRubyならこんな感じで書きたい(Rubyを例に出すのは、作りやすいから)

Display.set "display-1" do |d|
  d.set_resolution width: 1920, height: 1200
  d.set_colorBit: 32
  d.set_style: :classic
end

Account.add_user do | user |
   user.name = "abc"
   user.password =  "cde"
end

Server.add_ftp do |ftp|
  ftp.port = 21
  ftp.document_root = "ftp"
end

Server.add_http do |http|
  http.port = 80
  http.document_root ="htdoc"
end

App.remove /(jdk|jre)/
App.add installer: "c:¥¥jdk1.6.045.installer.exe", to_path: ""

Network.set "ローカルネットワーク1" do |n|
  n.name="LAN-A"
  n.ip_v4 = "192.168.10.111"
  n.netmask="255.255.255.0"
  n.gateway = "192.168.10.1"
end

とりあえあずDisplay周りだけでもチャレンジしようか・・・。

os x bash で cd + ls を行うコマンド

cdした後にlsを行う。だけのコマンドをbashに追加する。

  • .bash_profileを編集する

以下を追加する。

function cdd() {
  ¥cd "$1";
  if [ $? -eq 0 ]; then
    ls; 
  fi  
}

上記例では、cddというコマンド名にしている。 コマンド名をcdにするとlsしたくないときもlsされてしまうし、cdlsやcdlだと左手も使う必要があるので、片手で打てるcddとした。

  • .bash_profileをリロードする

ターミナルを再起動をする。 または次のコマンドを実行する。

source .bash_profile

Windows net shareとrubyを利用して共有フォルダのサイズを取得する

仕事で共有フォルダのサイズを定期的に採取する必要があったので、共有名とパスを取得するスクリプトをrubyで作成してみた。

共有名とパスの取得の仕方

Windows で net shareを実行すると、次のような共有フォルダの一覧が取得できる。

> net share

共有名       パス      リソース
IPC$
C$
D$
Test       C:¥Test
MyShare    D:¥MyShare
LonguuuuName                    # 共有名が長いとパスは次の行に表示される
           D:¥AAA¥LonguuuuN...   # パスが長いと途中で切れる

上記のようにこれだけではフルパスが取得できない事があるので、 net share 共有名 を利用してフルパスを取得する。

 net share Test # 共有フォルダTestに関する詳細な情報が標準出力される

と言うわけで、net shareで共有名の一覧を取得して、そこからnet share 共有名で、フルパスを取得するrubyスクリプトを作成した。

# coding: utf-8

require 'kconv'

module Windows
module Net

 def self.each_share_folder(&block)
    result = `net share`.toutf8
    state = :prev_header
    result.each_line do |line|
      if line =~ /^-/
        state = :after_header
        next
      end

      # この正規表現. 共有名に空白が含まれると正しく
      # 処理できない。
      if state == :after_header and line =~ /^([^\s$]+)/
        share_name = $1.chomp
        if share_name.length > 0
          puts share_name
          # 共有名に空白があるとここで失敗する。
          command = "net share #{share_name}"
          detail = `#{command.tosjis}`.toutf8
          parse_detail(detail, &block)
        end
      end
    end
  end

private
 def self.parse_detail(detail, &block)
    name = ""
    path = ""
    detail.each_line do |line|
      if line =~ /^共有名\s*(.*)/
        name = $1.chomp
      elsif line =~ /^パス\s*(.*)/
        path = $1.chomp
      end
    end
    unless name.empty? or path.empty?
      block.call name, path if block
    end
 end
end
end

github

使い方

Windows::Net.each_share_folderを実行すると、見つかった共有名とパスをブロックに渡す。 (下記サンプル参照)

 
require './windows/net/net_share.rb'

Windows::Net.each_share_folder do |name, path|
 puts name + "," + path # 共有名とフルパスを標準出力する.
end

ファイルサイズの取得方法は別の記事で。

C++講座 その5 サイズとバイトオーダー

サイズ

32bit CPUでWindows系の環境では各型は次のようなサイズになっている。

型名 サイズ(byte)
char 1
short 2
int 4
long 4
float 4?(後日確認)
double 8

「一般的な」としたのは、これらのサイズはCPUやOSの環境に依存するため。64bit環境では上表とは異なる値になる。

C++言語により規定されているのは、次のルールのみで「intはNバイト」という規定はない。

1sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)
1 <= sizeof(bool) <= sizeof(long)
sizeof(char) <= sizeof(wchar_t) <= sizeof(long)
sizeof(float) <= sizeof(double) <= sizeof(long double)
sizeof(N) ≡ sizeof(signed N) <= sizeof(unsigned N) // Nはchar,short,int,longのいずれか

C/C++での最大値・最小値の定義

limitsヘッダに各型の最大値、最小値の定数値が定義されている。

#include<limits>
#include<iostream>
using namespace std;

#define cout_limit(T) cout << #T << "," << sizeof(T) << "," << numeric_limits<T>::min() << "," << numeric_limits<T>::max() << endl

int main() {
  cout_limit(bool);
  cout_limit(char);
  cout_limit(short);
  cout_limit(int);
  cout_limit(long);
  cout_limit(float);
  cout_limit(double);
  cout_limit(long double);
  return 0;
}

バイトオーダー

short以上の2バイト以上の型の場合、CPUによって値の配置順序が異なる。

トルエンディアン

Intel系のCPUの場合、リトルエンディアンという順序で値は配置され、次のようになる。

short a = 0;

aが0x1000番地に配置されたと仮定すると、次のように値は設定される。

アドレス
0x1000 0
0x1001 0

a = 1;

アドレス
0x1000 1
0x1001 0

a=255;

アドレス
0x1000 FF
0x1001 0

a = 256;

アドレス
0x1000 0
0x1001 1

これは16進数でメモリをダンプ出力した際、見た目と逆に表示される。(左の桁の方が小さい)

ダンプ(16進数)
0 00 00
1 01 00
255 FF 00
256 00 01

ビッグエンディアン

SH2,SH4や今はなきサンマイクロシステムズのSPARCで採用されている。 リトルエンディアンとは逆順に値が設定される。

short a = 0;

aが0x1000番地に配置されたと仮定すると、次のように値は設定される。

アドレス
0x1000 0
0x1001 0

a = 1;

アドレス
0x1000 0
0x1001 1

a=255;

アドレス
0x1000 0
0x1001 FF

a = 256;

アドレス
0x1000 1
0x1001 0

こちらは16進数でメモリをダンプ出力した際、見た目通りに表示される。(右の桁の方が小さい)

ダンプ(16進数)
0 00 00
1 00 01
255 00 FF
256 01 00

移植性とネットワークバイトオーダー

同じ環境のみでデータを授受している場合、バイトオーダーは問題ない(送信元、受信先ともに同じバイトオーダーのため)。しかし、バイトオーダーの異なる環境で授受する場合は、どちらかに統一する必要がある。例えばTCP/IPの場合、一般的にビッグエンディアン(ネットワークバイトオーダー)に合わせる。 参考 Wikipedia エンディアン

2014/2/15 補足

エンディアンはバイトのみならず、ビットにも存在する。これもCPU等の環境により異なるので移植の際に問題となる。

参考 エンディアンについて (ビット編)