メールログの時間がずれる時の対処
メール送信と受信のため、PostfixとDovecotをインストールしましたが、
メールログ(/var/log/maillog)に出力される時間がサーバ時間と9時間もずれていました。
色々ググって試して失敗したりしましたが、ついに解決できましたので、メモします。
以下のコマンドを実行したら、いけました。rootで行う必要があります。
cd /var/spool/postfix mkdir etc #既にあれば、スキップ cd etc cp /etc/localtime . service postfix restart service rsyslog restart
殆どのブログでは/etc/localtimeを/var/spool/postfix/etcにコピーすればいいと言っていましたが、
私が使うサーバではrsyslogの再起動も必要でした。
セッションストアに関してメモ
最近、RoR(Ruby on Rails)を勉強しています。
RoRでセッションデータはデフォルトでブラウザのクッキーに保存されます。
最初はServletのようにセッションIDだけ、ブラウザに送られて、実際のデータはサーバのメモリに保存されると思いました。
しかし、そうではなく、セッションに入れたすべてのデータがブラウザのクッキーに保存されるのでした。
これはまずいんじゃない?と思いました。
なぜなら、たとえ、クッキーのセッションデータが暗号化されていても理論的には復号化できるので、
セキュリティ上、安全ではないからです。
幸い、RoRではセッションストアを変更できます。
セッションデータをDBはもちろんのこと、Redisやmemcachedなどのキャッシュサーバに保存することも可能です。
RoRで本格的にウェブアプリケーションを開発する時にはセッションストアをクッキー以外に変更しましょう。
以下のgemはセッションデータをDBに保存します。
github.com
以下はredisです。
github.com
最後にmemcachedです。
github.com
どのセッションストアもセッションデータを一つのAPサーバのメモリでなく、クッキーやDBなどの共有ストレージに保存するとの共通点がありますね。
こうなると、APサーバの冗長化時にセッションを同期するためにクッキーにサーバのIDを送るとか、セッションレプリケーションなどを行う必要がないから、便利だと思います。
勉強メモ1
Rubyは以前遊びぐらいでしか触ったことがありませんが、
今回勉強したいと思い、学習を始めることになりました。
ただ、以前のように分厚い本を買って、表紙(まえがき)から最後の隅々まで
読んで写経することはしないつもりです。
時間を節約し、効率的に勉強したいと思います。
その方法として、既存のプログラミング言語に共通しそうな部分は除いて
Rubyにしかないものだけを勉強する、差分学習を取ります。
この記事はその学習メモです。
文字列中の変数
"#{変数名}"
コメント
- 1行 : #
- ブロック =begin ~ =end
定数
大文字。変更不可能。
多重代入
q, a, z = 1, 2, 3 q, a, *z = 1, 2, 3, 4, 5 # zには配列として代入。1, 2, [3, 4, 5] q, a = 0, 1 q, a = b, z ar = [3,4] q,a = ar # 3, 4 ar = [1, [2, 3], 4] q, (a1, a2), z = ar # 1, 2, 3, 4
分岐
if修飾子とunless修飾子
文の右にifやunlessを書くことができる。ミニif文、ミニunless文ってことか。
a = 1 "Hi" if a > 1 # nil "Man" if a == 1 # Man "Hoi" unless a > 1 # Hoi
===
==に似ているが、左辺がリテラル(クラス、数値、文字列など)の場合、右辺との比較を柔軟に行う。
例えば、String == "a"だと、false。String === "a"だと、"a"がStringクラスのインスタンスという比較を行い、trueがリターンされる。
同一性
オブジェクトの値を比較するなら、==を使えばいい。厳密にオブジェクトの同一性を比較するなら、eql?を使う。
Javaとは反対ですね。
繰り返し
- untilはwhileの反対。
- nextはJavaのcontinue。
- redoは同じことをもう一回繰り返す。
times
10.times do print "Duke" end
配列
names = ["Duke", "Foo"] names.each do |n| puts n end
ハッシュ
person = { name: "Duke", job: "Engineer" } person.each do |key, value| puts "#{key}: #{value}" end
ブロック
1行にまとめるときは{ ... }、複数行に分ける場合、do ... end
メソッド
- 最後にreturn文は省略してもよい。
- 可変長引数は引数に*argsと書く。
キーワード引数
引数名:デフォルト値
def m1(q:1, a:2, z:3) q + a + z end m1(z:5,q:3) # 10
ブロック付きメソッド
def m1 puts "Hello!" yield # これがブロックを実行する。 end m1 do puts "Hey Duke!" end # Hello! # Hey Duke!
引数がハッシュの場合、{}を省略可能
def m(q) q end m({ "n" => "d", "t" => 5 }) # { "n" => "d", "t" => 5 } m("n" => "d", "t" => 5) # { "n" => "d", "t" => 5 } m(n: "d", "t": 5) # { "n" => "d", "t" => 5 }
クラス
アクセスメソッド
getter, setterのようなもの。
一々メソッドを定義してもいいが、getter/setterの数が多いと、面倒。
代わりに以下のものを使えばgetterとsetterを自動生成してくれる。
attr_reader :変数名
getter
attr_setter :変数名
setter
attr_accessor :変数名
getter + setter
クラスメソッド
class << オブジェクト ~ end形式がある。
オブジェクトにクラス名を指定すると、以下の例のようにクラスメソッドになる(Classクラスのインスタンスにメソッドを追加)。
しかし、オブジェクトに特定インスタンス変数を指定すると、そのインスタンスのみにメソッドが追加される。
まるでJavascriptでオブジェクトに自由にメソッドを追加できるのと同じ感じだ。
# クラス内で定義 class DukeLab class << self def classMethod1 "Hey" end end end DukeLab.classMethod1 # Hey # 特異クラス形式で定義。既にDukeLabクラスが定義されなければならない。 class << DukeLab def classMethod2 "You!" end end DukeLab.classMethod2 # You! # クラスの外から定義 def DukeLab.classMethod3 "Man!" end DukeLab.classMethod3 # Man! # クラス内で定義 class DukeLab def self.classMethod4 "Woman!" end end DukeLab.classMethod4 # Man!
定数
クラス名::変数名
アクセス制限
何も指定しなければ、public。
public, private, protectedキーワードを使ってアクセス制限を定義できる。
class DukeTest def m1 "Duke1" end public :m1 #デフォルト def m2 "Duke2" end private :m2 end dt = DukeTest.new dt.m1 dt.m2 # エラー
まとめてprivateにする
class DukeTest def m1 "Duke1" end private # これより下はprivate def m2 "Duke2" end end
getだけ可能にする。
class DukeTest attr_accessor :q, :a private :q=, :a= # xとyにsetできないようにする。 def initialize(q, a) @q, @a = q, a end end dt = DukeTest.new dt.q dt.q = 8 # エラー
継承
class クラス < スーパークラス
モジュール
Scalaのtrait、Javaのdefault interfaceって感じ?
クラスでinclude モジュール名すると、そのクラスにモジュールの全てのメソッドが追加される。
モジュールをクラスに入れることをMixinという。
module Mod1 def m1 "variable : #{@q}" end end class Duke include Mod1 def initialize(q) @q = q end end d = Duke.new(5) d.m1 # variable : 5
Object.extend
特定オブジェクトにモジュールをMixinする。
module Mod1 def m1 "variable : #{@q}" end end class Duke def initialize(q) @q = q end end d1 = Duke.new(8) d1.extend(Mod1) d1.m1 # variable : 8
extendでクラスメソッドを追加
module Mod1 def m1 "Hi!" end end module Mod2 def m2 "Man!" end end class Duke extend Mod1 #クラスメソッド include Mod2 #インスタンスメソッド end d1 = Duke.new d1.m1 # エラー。インスタンスメソッドではない。 Duke.m1 # Hi! d1.m2 # Man! Duke.m2 # エラー。クラスメソッドではない。
演算子
範囲演算子
Range.new(x, y)又はx..yを使う。
for i in 1..10 puts i end (1..10).to_a # 1,2,3,4,5,6,7,8,9,10 (1...10).to_a # 1,2,3,4,5,6,7,8,9 yを除く。
演算子定義
class Apple attr_reader :n, :p def initialize(n, p) @n = n @p = p end def +@ # 単項演算子の場合、後尾に@をつける。 "Plus" end def +(other) self.class.new(n + other.n,p + other.p) end def inspect "n : #{n}, p : #{p}" end end a = Apple.new(1, 10) b = Apple.new(2, 20) +a # "Plus" a + b # n : 3, p : 30
例外
キーワードが違うだけで殆どJavaと同じ。
begin # try ... rescue => ex # catch ... retry # beginに戻って再実行。無限ループに注意。 ensure # finally ... end
メソッド全体をtry-catchしたい場合、beginとendは省略可能。
def duke ... rescue => ex # catch ... retry # beginに戻って再実行。無限ループに注意。 ensure # finally ...
例外のスローはraiseキーワードを使う。
rescue修飾子
A rescue Bで、Aが失敗すると、Bが実行される。ミニtry-catchのようなもの。
File.open("duke.txt") rescue "-_-Error" # -_-Error
ブロック
処理のかたまり。
メソッドに何かを実行するブロックを渡すと、前後処理は自動でやってくれるケースが多い。
例えば、以下の場合、ファイルをオープン(前処理)し、その内容を一行ずつ表示する。
ファイルを閉じる処理(後処理)は自動でやってくれる。
File.open("README.md") do |file| file.each_line do |line| print line end end
ブロックの実行
ブロックはメソッドでyieldコマンドで実行する。
yieldコマンドに引数を指定すると、ブロックに渡される。
def m1(q) v = yield(q + 1) puts "value : #{v}" end m1(5) { |n| "wow => #{n}" } # value : wow => 6 m1(7) do |n| # value : haha => 7 "haha => #{n}" end
制御
break, next, redoをブロック内でも使うことができる。
def m1(q) puts "Step1" yield(q) puts "Step2" yield(q + 1) puts "Step3" yield(q + 2) end m1(1) do |q| # Step1 Block Step2 Block Step3 Block => 3!!! if (q == 5) break end puts "Block" "#{q}!!!" end m1(4) do |q| # Step1 Block Step2 => nil if (q == 5) break end puts "Block" "#{q}!!!" end # breakやnextに戻り値を指定できる。 m1(4) do |q| # Step1 Block Step2 => Break! if (q == 5) break "Break!" end puts "Block" "#{q}!!!" end m1(4) do |q| # Step1 Block Step2 Step3 Block => 6!!! if (q == 5) next end puts "Block" "#{q}!!!" end
redoは無限ループの危険がありそうだ。
Proc
ブロックをオブジェクトにしてくれるもの。"ブロックをProcオブジェクトにする"と言い方をするらしい。
Procオブジェクト化したブロックはcallメソッドで呼べる。
def m1(q, &b) # &はブロックをProcオブジェクトに自動変換する。 v = b.call(q) "yaho!#{v}" end m1(5) do |q| # yaho!haha5 "haha#{q}" end myb = Proc.new do |q| "haha2#{q}" end m1(8, &myb) # yaho!haha28 m1(8, myb) # エラー。&をつける必要がある。 def m2(q, b) v = b.call(q) "kaho!#{v}" end myb2 = Proc.new do |q| "kaha2#{q}" end m2(9, myb2) # kaho!kaha29 #別の書き方 : procメソッド myb3 = proc do |q| "kaha3#{q}" end m2(10, myb3) #kaho!kaha310 #別の書き方 : lambda myb4 = lambda do |q| "kaha4#{q}" end m2(11, myb4) #kaho!kaha411 #別の書き方 : -> myb4 = ->(q) { "kaha5#{q}" } m2(12, myb4) #kaho!kaha512 #procとlamdbaの違い1 : lamdbaの方が引数のチェックが厳密だ。 myb5 = proc do |q,a| print [q, a] end myb6 = lambda do |q,a| print [q, a] end myb5.call(2) # [2,nil] myb6.call(2) # エラー : ArgumentError: wrong number of arguments (1 for 2) #procとlamdbaの違い2 : procを作ったメソッド外でproc内でreturnすると、エラーになる。 def m1 proc { return 1 } end def m2 lambda { return 2 } end p = m1 p.call # エラー(procが自分を作ったm1の外で呼びだされ、returnしたため) : LocalJumpError: unexpected return d = m2 d.call # 2
今日はここまで。
webapps配下でないディレクトリにリソースを置く
Tomcatで、ウェブアプリで使われるリソースをwebapps配下でないディレクトリに置きたい場合あります。
例えば、リソース(画像やJSPなど)をアップロードしてウェブアプリの画面を動的に構成したい時です。
またお客様がウェブアプリ本体のソースを修正することなく、カスタマイズできるようにしたい時もありますね。
もし、そういうリソースをwebapps配下におくと、
ウェブアプリをデプロイするたびに既存のリソースが消えてしまうので、困りますね。
こういう場合、Tomcat8に追加されたResources Componentを使えばいいです。
以下のようにserver.xmlのContext要素配下にResources要素とその下のPostResources要素を追加します。
<Context docBase="myweb" path="" reloadable="false"> <Resources allowLinking="false"> <PostResources className="org.apache.catalina.webresources.DirResourceSet" base="${other}/myres" webAppMount="/myres" /> </Resources> </Context>
PostResourcesのbaseにはリソースが位置する絶対パスを指定します。
${other}のようにJVMのシステムプロパティを指定することもできます。
webAppMountにはURLのパス(ウェブアプリのルートパスで次の部分)を指定します。
上記の場合、URLの後ろに/myresと入力した場合、
baseディレクトリにあるリソースを読み込んでレスポンスとして返します。
リソースの位置がwebappsでないだけで、既存webapps配下にあるリソースとまったく同じです。
良い機能ですね。
機械学習の種類とR言語でのパッケージ
機械学習の種類とR言語でのパッケージをざっくりと整理してみました。
自分の理解に役に立つ形態で整理したため、書籍に出るようなまともなものとは違うところがあります。
また、間違った部分もありえますので、気付き次第、修正していくつもりです。
予測
分類(Classification)
データを決まったカテゴリにグループ分けすることです。
kNNアルゴリズム
classパッケージのknn関数
決定木
C5.0アルゴリズムの実装では、C50パッケージのC5.0()関数
回帰(Regression)
数値の予測を行うことです。
線形回帰
statsパッケージのlm(関数)
複数用途
神経網
人間の脳を構成するニューロンの仕組みをコンピューターで真似て予測を行います。
Neuralnetパッケージのneuralnet()関数。
SVM(Support Vector Machine)
kernlabパッケージのksvm()関数。
Apache POIのExcelファイルで日本語セルの列幅を自動調整
Apache POIで列幅を自動で調整してくれる
Sheet#autoSizeColumnメソッドがあります。
数字や英語の場合、ちゃんと列幅を調整してくれるようですが
日本語の場合、Sheet#autoSizeColumnメソッドを呼び出しても、
幅がうまく調整されません。
幅が微妙に足りなかったりします。
こういう場合、セルにフォントを明示的に指定すると、
列幅が問題なく調整されます。
// ...中略... // 日本語での列幅の自動調整のため、フォントを明示的に指定する。 CellStyle cellStyle = workbook.createCellStyle(); Font font = workbook.createFont(); font.setFontName("Serif"); cellStyle.setFont(font); // ... 中略 ... // 列幅を自動調整する。ここでは最初(0番目)の列の幅を自動調整する。 sheet.autoSizeColumn(0, true);
JDKのJavascript(nashron)で外部のJavaクラスを呼び出す方法
自分が作ったクラスや外部のライブラリを呼び出して、
機能を作りたい時があります。
普通にJavaで作ってもいいですが、
コンパイルが必要ですし、
早く作りたいのにJavaの厳格な文法がちょっと面倒です。
ScalaやGroovyなどを使って
軽くスクリプトを作るのもいいですが、
JDKに標準で入っていないから、やはり面倒。
それでJDK(バージョン8)に標準で入っているJavascriptエンジンnashronを
使ってみました。
しかし、nashronはなかなか外部クラスを認識してくれませんでした。
jrunscriptコマンド(またはjjsコマンド)の実行時に
−classpathや-cpにクラスパスをjavaコマンドと同じ方法で指定したのにも関わらず、
いつもClassNotFoundExceptionが発生して困っていました。
色々と試した結果、やっと外部のJavaクラスを認識してくれたので、その方法をメモします。
まず、jrunscriptの実行時に以下のようにクラスパスを指定します。
Linux(Ubuntu)を基準に説明します。
例えば、/dukelab/libに10個のjarファイルがあって、それらをjrunscriptにクラスパスとして通したいなら、以下のように起動します。
jrunscript -cp `echo /dukelab/lib/* | tr ' ' ':'`
ちょっと複雑で、これ以外の方法もあると思いますが、
今のところ、これで行けました。
単純にjrunscript -cp /dukelab/lib/*とすると、うまく行きません。
Linuxのシェルで"/dukelab/lib/*"が式として評価されて、
jrunscript -cp /dukelab/lib/a.jar /dukelab/lib/b.jar... のように
展開されて実行されます。
コマンドプロンプトでは空白文字で引数を分離していますから、
/dukelab/lib/b.jarがスクリプトファイルとして認識され、jrunscriptが実行されます。
当然/dukelab/lib/b.jarはスクリプトと関係ないバイナリのファイルですから、エラーになってしまいます。
それで上記の`echo /dukelab/lib/* | tr ' ' ':'`のように/dukelab/lib/*の展開後に、
trコマンドで空白文字をクラスパスの区切り文字である:に変換する処理を追加しました。
こうすると、実際には
jrunscript -cp /dukelab/lib/a.jar:/dukelab/lib/b.jar...
のようになるので、クラスパスとしてうまく認識できるようになります。
もし、jarファイルでなく、classファイルが置かれているディレクトリなら、もっと簡単です。
例えば、/dukelab/classes配下にJavaクラスがあるなら、
以下のように指定します。
jrunscript -cp /dukelab/classes
クラスパスを複数指定する時は:(コロン。Windowsでは;(セミコロン))で区切って下さい。
これで準備が終わり、Javascriptの話になりますが、
dukelab.js.test1パッケージにあるTestOneクラスと
dukelab.js.test2パッケージにあるTestTwoクラスをJavascriptで呼び出してみます。
2つのクラスはSystem.out.printlnを呼び出すごく単純なクラスなので、内容は割愛します。
var pkgs = new JavaImporter( Packages.dukelab.js.test1, Packages.dukelab.js.test2 ); with(pkgs) { print("TestOne : " + TestOne.getString()); print("TestTwo : " + TestTwo.getInt()); }
実行すると、以下のように表示されます。
TestOne : wow! TestTwo : great!
つまりいうと、Packagesオブジェクトの次に使うJavaクラスの完全修飾名を指定して呼び出すということです。
ただ、いつもPackages.dukelab.js.test1.TestOne.getString()...ように呼び出すのは辛いから
上記のようにwith文を使ってパッケージを省略して使うのがいいでしょう。
with文はJavascriptではスコープが曖昧になってしまうため、使わない方がいいと言われていますが、
JavascriptでJavaクラスを使う時は便宜上、必須ではないかと思います。
ということで少なくともJavaの中のJavascriptでは、with文は当分健在だろうと勝手に思っています。
そのうち、新しい文法ができるかもしれませんが...
最後にJavascriptにおけるJavaクラスの呼出方法をまとめておきます。
// 完全修飾名で呼出し print(Packages.dukelab.js.test1.TestOne.getString()); // with文でパッケージ(一つ)を省略 with (Packages.dukelab.js.test1) { print(TestOne.getString()); } // with文でパッケージ(一つ以上)を省略 with (new JavaImporter(Packages.dukelab.js.test1, Packages.dukelab.js.test2)) { print(TestOne.getString()); print(TestTwo.getInt()); }