モーグルとカバとパウダーの日記 このページをアンテナに追加 RSSフィード Twitter

モーグルやカバ(EXカービングスキー)、山スキー(BC)の山行記録などがメインの日記です。
いろんな条件のいろんなところを、その時々の条件にあった滑り方で楽しむ、フリースキーをして遊んでいます。

検索で来られた方は、上の検索窓から再度検索していただくか、右サイドバーのカテゴリーやトピックスの項目で絞り込んでみてください。
仕事柄、コンピュータ系のネタも多いので、スキー関連ネタだけ読みたい方は[ski]、コンピュータ関連ネタは[pc]、スパム関連ネタは[spam]で絞り込んでください。

2015-08-03 (Mon)

[]vagrantなどで自動構築したテスト環境VMに複数ホスト名でアクセスする vagrantなどで自動構築したテスト環境VMに複数ホスト名でアクセスするを含むブックマーク vagrantなどで自動構築したテスト環境VMに複数ホスト名でアクセスするのブックマークコメント

vagrant+ansibleでCentOS6のテスト環境を自動構築するものを作っているのですが、その環境でvirtualホストの設定をしている場合に、複数のホスト名で接続できるようにしたい、と考えました。


テスト環境でやる場合、avahi(Bonjour)を使って名前解決をさせるのが一番お手軽で、Windowsからも「Bonjour Print Services」を入れれば利用できます。

WindowsからVMware上のLinuxへBonjour使ってサーバ名で接続する - モーグルとカバとパウダーの日記


しかし、avahi-daemonはそのままだと1つのホスト名しかサービスしてくれません。

ただ、avahi-daemonを複数ホスト名に対応できるようなスクリプトがあり、それを使うと複数名での接続が出来るようになります。


…と書いてますが、最初airtonix/avahi-aliasesを導入しようとしたもののなかなか出来ず、

からの一連のリプライでやっと出来るようになったわけですが…


まず、avahi-daemonを動かすように設定します。

avahi-daemonはmessagebus(dbus)というものが必要で、先にこちらのデーモンを動かしておく必要があります。実は複数ホスト名に対応する機能を後付するためにもこの機能が利用されているようです。

$ sudo yum install avahi
$ sudo service messagebus start
$ sudo service avahi-daemon start

複数ホスト名を使えるようにするために下記スクリプトを利用しました。

Register a mDNS/DNS-SD alias name for your computer using the Avahi daemon

またこのスクリプトを使うためにpython-avahiというライブラリが必要になるのですが、それはavahi-ui-toolsに含まれているため、それも入れてやります。

$ sudo yum install avahi-ui-tools
$ git clone https://gist.github.com/3168336.git
$ chmod +x 3168336/avahi-alias.py
$ sudo cp 3168336/avahi-alias.py /usr/local/bin/

設定と起動はシンプルに「/etc/rc.local」に下記行を追加して行いました。

/usr/local/bin/avahi-alias.py hoge1.local hoge2.local &

この例だと、サーバ名の他に「hoge1.local」「hoge2.local」もaliasとして使えるようになります。


Macの場合は最初からBonjourが入っているため、なにもしなくても使えます。


WindowsからBonjourを使えるようにするには、Appleの提供しているBonjourのサービスをインストールします。

Bonjour Print Services for Windows v2.0.2

Bonjour Print Servicesとなっていますが、Printだけでなく普通にBonjourのサービス情報取得が行えます。

Petit Tech: Linuxでのmdns(avahi/Bonjour)による名前解決。」によるとiTunesをインストールすることでも利用できるようになるそうです。


これでホスト名が「hoge」で、alias設定が上記の例だと「hoge.local」と「hoge1.local」「hoge2.local」の名前でアクセスできるようになります。

トラックバック - http://d.hatena.ne.jp/stealthinu/20150803

2015-07-31 (Fri)

[]ansibleの動作条件と確認方法 ansibleの動作条件と確認方法を含むブックマーク ansibleの動作条件と確認方法のブックマークコメント

ansibleの良い所は、動作するのにクライアント環境にsshで繋がってpythonが動けば良いだけ、というところです。


が、なんか環境によって動かなかったりすることがあります。

確認すべき点をまとめてみました。


まず基本ですが、sshで接続できるか確認します。

接続できるなら、リモート環境のコマンドが実行出来るかを確認します。


$ ssh foo@example.com hostname
www.example.com

自分は、sshで接続できるのにリモートのコマンドが実行できず、調べてみたらログインシェルが /etc/shells に書かれていなかったため、それでエラーになって実行できなくなっていました。


コマンドが実行できてもダメな場合があります。

実は ansible はデフォルトの設定だと sftp の接続も出来ないといけないようです。



CentOS5や6ではデフォルトで sftp が使えないようになっているため、問題がなければ


/etc/ssh/sshd_conf

Subsystem       sftp    /usr/libexec/openssh/sftp-server

にコメントを外してsshd再起動してやれば良いです。


ただ、なにかの理由で sftp は使わないようにしたい場合、下記のエントリーを参考に


「SFTP disableなCentOS環境でansibleを使う」

http://tagomoris.hatenablog.com/entry/20140318/1395118495


ansibleを動かすディレクトリ


ansible.cfg

[defaults]
transport=ssh

[ssh_connection]
ssh_args=
scp_if_ssh=True

と設定すれば動きました。

トラックバック - http://d.hatena.ne.jp/stealthinu/20150731

2015-07-28 (Tue)

[]vagrant+ansibleなどでテスト環境の構築自動化する場合のsshキーペアの扱い vagrant+ansibleなどでテスト環境の構築自動化する場合のsshキーペアの扱いを含むブックマーク vagrant+ansibleなどでテスト環境の構築自動化する場合のsshキーペアの扱いのブックマークコメント

について、リプライいただいたことをまとめました。


CMSで動いているproduction環境に、機能追加やテスト等を行うために、vagrant+ansibleで開発環境を構築する設定を書いていました。

ホストPC上にvagrantでVMが生成され、ansibleでapachetomcatCMS等の組み込みと設定を行い、production環境から現在のデータやファイルをコピーしてきて、ほとんどミラーに近い環境を構築します。


このとき、データベースや追加されたファイルなどを取ってくる処理を、production環境上でダンプやtarしたものをfetchで一度ホストPCに持ってきて、それをVM上に展開するという処理にしていました。

しかし、転送が二度手間になっていて時間もかかるため、例えばファイルについてはsynchronize(rsync)など使ってVM上から直接productionサーバの内容を最新のものに合わせたいと思いました。

ただそうするには、VMからproduction環境に接続するためのsshキーペアの設定が必要になります。

そこでVMにホストPCの秘密鍵をansibleで突っ込んでやればいいだろう、と思ったのですが、それはセキュリティ的にはやっぱ良くないよな…と思って書いたのが冒頭のツイートでした。


それでこの件に対し @_hito_ さんから色々アドバイスをいただきました。

で、後から見直すと下記2ツイートにまとまっちゃうのですが、最初はイマイチピンと理解できず…

何件か質問して噛み砕いて説明していただきました _o_


元々自分が考えていたのは、ホストPCとproduction環境の間で通常使うための鍵ペアをそのまま使い、VM秘密鍵を送り込んで接続するイメージでした。

しかしこれだと、その開発環境のVMが侵害された場合、ホストの秘密鍵が漏れてしまいます。


そこで、データコピー専用の鍵ペアを作って、それの公開鍵をproduction環境に入れておきます。

vagrantで生成したVMには、そのデータコピー専用の秘密鍵を入れてやります。

この下記ペアはデータコピー専用のものなので、もしどこかのVMが侵害されて秘密鍵が漏れても、入れる場所は結局コピー元のところだけなので、それは使いまわしても良いわけです。

トラックバック - http://d.hatena.ne.jp/stealthinu/20150728

2015-07-02 (Thu)

[]MSYS2のgitgithubからcloneしようとしてSSL証明書の問題でエラーになる MSYS2のgitでgithubからcloneしようとしてSSL証明書の問題でエラーになるを含むブックマーク MSYS2のgitでgithubからcloneしようとしてSSL証明書の問題でエラーになるのブックマークコメント

とある原稿を共同で書くために、githubのプライベートリポジトリを使って、そこにcommitしてこうということになりました。

んで、作ってもらった場所からやっとこさcloneしようとしたのですが。

fatal: unable to access 'https://github.com/…': error setting certificate verify locations:

CAfile: /usr/ssl/certs/ca-bundle.crt

CApath: none

とか言われまして。


自分はWindows8.1でSourceTreeを利用していますが、内蔵のgitではなくMSYS2を入れてそのgitを使っています。

この問題は結構よくある話しらしく、色々と出てくるのですがこちらが参考になりました。


Githubの証明書問題をまっとうに解決する - Limitの日記

http://d.hatena.ne.jp/limitusus/20120529/1338306372


自分の場合、MSYS2のgitの証明書を新しくすればよいので、MSYS2のターミナルから

% cd /usr/ssl/certs
% curl http://curl.haxx.se/ca/cacert.pem -o ca-bundle.crt

として新しいCA証明書を入れてやることで解決しました。

トラックバック - http://d.hatena.ne.jp/stealthinu/20150702

2015-06-02 (Tue)

[]JavaでWebフォームに入力された内容を文字化けせずにメールで送る JavaでWebフォームに入力された内容を文字化けせずにメールで送るを含むブックマーク JavaでWebフォームに入力された内容を文字化けせずにメールで送るのブックマークコメント

Webでフォームに入力された内容をメールでどこかに送る、というのはすごくありふれた内容だと思います。

が、Javaで普通に書くと、いろんな理由で文字化けが発生してしまいます。

一番よくあるのがUTF-8→JIS(ISO-2022-JP)に変換するときに、変換できなくて「?」になってしまうというやつです。


そこで、文字化けが起きないように事前にいくつかフィルタを掛けてやる必要があるのですが、あまりまとまった情報がなくて困ったのでまとめてみました。


大きく下記3種のフィルタを掛けることで対応しました。

  • 波ダッシュやハイフン
  • IBM-UnicodeMS-Unicodeの違い(「¢」や「£」など)
  • HTMLエンティティ(「<」のようなもの)

波ダッシュ問題はとても有名ですが、その上UTF-8には色んな波ダッシュやハイフンがあり、一つに対応してあっても他ので化けたりします。

どうしたもんかと思っていたら、下記ページに波ダッシュやハイフンの各文字コードでの対応状況がまとめられており、大変に参考になりました。

また、変換コードもありましたので、そこに追加する形で他の化ける文字の対応をおこないました。

Unicodeの似た文字を整理してみた - y-kawazの日記


他にもIBM-UnicodeMS-Unicodeの違いにより化けてしまうという問題があります。

これで化けるものは、波ダッシュの他に「¢」や「£」などがあります。下記のページを参考にしました。

UTF-8での文字化け - mokkouyou2001の日記

perlでメール送信時の いわゆる波ダッシュ「〜」問題 | clicktx::Tech::Memo


また、接続環境なのかクライアントによってなのか、フォームに入力された記号のいくつかが、例えば「-」が「−」のように、HTMLエンティティに変換されて送られてくる場合があるようです。

これはどういった場合に、どの記号が変換されるのかということが調べきれなかったため、全てのHTMLエンティティを変換することにしました。

これには StringEscapeUtils クラスの unescapeHtml4 を利用しました。


これらをまとめたものが以下のコードです。

/**
 * HTMLエスケープ文字、UTF8→JISへの変換で化ける文字、を変換する
 * @param str
 * @return 変換された文字列を全て戻した文字列
 */
public String unescapeForMail(String str) {
  String result = str;
  result = StringEscapeUtils.unescapeHtml4(result);
  result = normalizeSimilarCharacter(result, "iso-2022-jp");
  return result;
}

/**
 * 文字化けの原因になる文字を、文字化けない文字に置換します。
 * http://d.hatena.ne.jp/y-kawaz/20101112/1289554290
 * http://perl.no-tubo.net/2011/01/12/perl%E3%81%A7%E3%83%A1%E3%83%BC%E3%83%AB%E9%80%81%E4%BF%A1%E6%99%82%E3%81%AE-%E3%81%84%E3%82%8F%E3%82%86%E3%82%8B%E6%B3%A2%E3%83%80%E3%83%83%E3%82%B7%E3%83%A5%E3%80%8C%E3%80%9C%E3%80%8D%E5%95%8F/
 * @param str
 * @param encoding 外部出力予定の文字コード(この値により置換テーブルが代わります)
 * @return
 */
public static String normalizeSimilarCharacter(String str, String encoding) {
    if(str == null || encoding == null) {
        return str;
    }
    encoding = encoding.toLowerCase();
    if("windows-31j".equals(encoding)) {
        return StringUtils.replaceEach(str, SIMILAR_CHARS_W31J_FROM, SIMILAR_CHARS_W31J_TO);
    } else if("shift_jis".equals(encoding)) {
        return StringUtils.replaceEach(str, SIMILAR_CHARS_SJIS_FROM, SIMILAR_CHARS_SJIS_TO);
    } else if("euc-jp".equals(encoding)) {
        return StringUtils.replaceEach(str, SIMILAR_CHARS_EUCJP_FROM, SIMILAR_CHARS_EUCJP_TO);
    } else if("iso-2022-jp".equals(encoding)) {
        return StringUtils.replaceEach(str, SIMILAR_CHARS_ISO2022JP_FROM, SIMILAR_CHARS_ISO2022JP_TO);
    }
    return str;
}

//共通置換テーブル
private static final String[] SIMILAR_CHARS_COMMON_FROM = new String[]{
    "\u00AD", "\u2011", "\u2012", "\u2013", "\u2043", "\uFE63", //半角ハイフン
    "\u223C", "\u223E", //半角波線→半角チルダ
    "\u22EF", //3点
    "\u00B7", "\u2022", "\u2219", "\u22C5", //半角中点
    "\u2225", "\uffe0", "\uffe1", "\uffe2"  // ‖ ¢ £ ¬
};
private static final String[] SIMILAR_CHARS_COMMON_TO = new String[]{
    "\u002D", "\u002D", "\u002D", "\u002D", "\u002D", "\u002D", //半角ハイフン
    "\u007E", "\u007E", //半角波線→半角チルダ
    "\u2026", //3点
    "\uFF65", "\uFF65", "\uFF65", "\uFF65", //半角中点
    "\u2016", "\u00a2", "\u00a3", "\u00ac"  // ‖ ¢ £ ¬
};
//エンコーディング別置換テーブル
private static final String[] SIMILAR_CHARS_SJIS_FROM;
private static final String[] SIMILAR_CHARS_SJIS_TO;
private static final String[] SIMILAR_CHARS_W31J_FROM;
private static final String[] SIMILAR_CHARS_W31J_TO;
private static final String[] SIMILAR_CHARS_EUCJP_FROM;
private static final String[] SIMILAR_CHARS_EUCJP_TO;
private static final String[] SIMILAR_CHARS_ISO2022JP_FROM;
private static final String[] SIMILAR_CHARS_ISO2022JP_TO;
static {
    SIMILAR_CHARS_SJIS_FROM = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_FROM, new String[]{
        "\uFF0D"/*全角マイナス*/, "\u00AF"/*長音符号*/, "\u2015"/*強調引用*/, "\u3030", "\uFF5E"/*波線*/
    });
    SIMILAR_CHARS_SJIS_TO = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_TO, new String[]{
        "\u2212"/*全角マイナス*/, "\uFFE3"/*長音符号*/, "\u2014"/*強調引用*/, "\u301C", "\u301C"/*波線*/
    });
    SIMILAR_CHARS_W31J_FROM = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_FROM, new String[]{
        "\u2212"/*全角マイナス*/, "\u2014"/*強調引用*/, "\u3030", "\u301C"/*波線*/
    });
    SIMILAR_CHARS_W31J_TO = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_TO, new String[]{
        "\uFF0D"/*全角マイナス*/, "\u2015"/*強調引用*/, "\uFF5E", "\uFF5E"/*波線*/
    });
    SIMILAR_CHARS_EUCJP_FROM = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_FROM, new String[]{
        "\uFF0D"/*全角マイナス*/, "\u2015"/*強調引用*/, "\u3030"/*波線*/
    });
    SIMILAR_CHARS_EUCJP_TO = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_TO, new String[]{
        "\u2212"/*全角マイナス*/, "\u2014"/*強調引用*/, "\uFF5E"/*波線*/
    });
    SIMILAR_CHARS_ISO2022JP_FROM = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_FROM, new String[]{
        "\uFF0D"/*全角マイナス*/, "\u00AF"/*長音符号*/, "\u2015"/*強調引用*/, "\u3030", "\uFF5E"/*波線*/
    });
    SIMILAR_CHARS_ISO2022JP_TO = (String[]) ArrayUtils.addAll(SIMILAR_CHARS_COMMON_TO, new String[]{
        "\u2212"/*全角マイナス*/, "\uFFE3"/*長音符号*/, "\u2014"/*強調引用*/, "\u301C", "\u301C"/*波線*/
    });
}
トラックバック - http://d.hatena.ne.jp/stealthinu/20150602

2015-05-20 (Wed)

[]GIMPで拡大縮小がうまくできなくなる問題 GIMPで拡大縮小がうまくできなくなる問題を含むブックマーク GIMPで拡大縮小がうまくできなくなる問題のブックマークコメント

嫁がGIMPを使って幼稚園のアルバム作成をしてるのですが、GIMPで拡大縮小の動作がなんかおかしくなるという問題が起きました。


探しても同じ問題にあたっている人がなかなかなかったのですが、この件とたぶん同じと思われます。

自分もこのスレッドと同様、別レイヤーに一旦コピーしてそこから拡大して対応しました。


レイヤーの拡大縮小ができません - GIMP質問掲示板

http://0bbs.jp/gimproject/4502/


実は、A4で印刷可能な領域などを半透明で設定してあるファイルを作ってあり、それを読み込んでから画像を別レイヤーで読み込んで拡大しようとしていました。

が、この元となるファイルで点くらいの大きさで領域選択がされていました

その上に画像を別レイヤーで読み込むと、読み込んだ画像全体が選択されたり新たな領域選択がされず、その小さな領域が拡大、となってしまっていました。

そのため、拡大しようとするとその何ドットかが拡大されるみたいになって、うまく動かない… となっていたのです。


そこで一旦矩形領域選択で別のところを選択して、その小さな領域選択が表示されなくなってから読み込むと普通に動くようになりました。

「選択」メニュー内の「選択を解除」を行ってもいいような気がします。


とりあえず、読み込んだファイルにすでに領域選択がされている状況で、別の画像を「レイヤーとして開く」をすると、領域選択の動きがおかしくなるのではないか、と思われます。

2015-05-08 (Fri)

[]JavaのSimpleDateFormatで多桁のミリ秒読み込みの謎 JavaのSimpleDateFormatで多桁のミリ秒読み込みの謎を含むブックマーク JavaのSimpleDateFormatで多桁のミリ秒読み込みの謎のブックマークコメント

CSVで渡されてくるデータの中に、日時データにミリ秒以下のものが付いているものがあり、そのパースをするとなんか読み込んだ時刻が微妙にずれてしまう、という問題が起こりました。


日付が「2015-05-08 00:00:00.123456789」のような形式でわたされるため、

String dateStr = "2015-05-08 00:00:00.123456789";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSSSS");
Date date = dateFormat.parse(dateStr);

のようにしてパースさせたのですが、9時間ズレるとかではなく中途半端に時間がずれてしまうのです。


なんでこうなるんだろう?と思ってちょっとテストコードを書いてみました。

out.println(testCalendar("2015-05-08 00:00:00",          "yyyy-MM-dd HH:mm:ss"));
out.println(testCalendar("2015-05-08 00:00:00.123",      "yyyy-MM-dd HH:mm:ss.SSS"));
out.println(testCalendar("2015-05-08 00:00:00.1234",     "yyyy-MM-dd HH:mm:ss.SSSS"));
out.println(testCalendar("2015-05-08 00:00:00.12345",    "yyyy-MM-dd HH:mm:ss.SSSSS"));
out.println(testCalendar("2015-05-08 00:00:00.123456",   "yyyy-MM-dd HH:mm:ss.SSSSSS"));
out.println(testCalendar("2015-05-08 00:00:00.1234567",  "yyyy-MM-dd HH:mm:ss.SSSSSSS"));
out.println(testCalendar("2015-05-08 00:00:00.12345678", "yyyy-MM-dd HH:mm:ss.SSSSSSSS"));
out.println(testCalendar("2015-05-08 00:00:00.123456789","yyyy-MM-dd HH:mm:ss.SSSSSSSSS"));

public String testCalendar(String dateStr, String formatStr) throws ParseException {
    String out = "";
    SimpleDateFormat dateFormat = new SimpleDateFormat(formatStr);
    Date date = dateFormat.parse(dateStr);
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    date = cal.getTime();
    out += "parsed date: " + dateFormat.format(date);
    return out;
}

結果

parsed date: 2015-05-08 00:00:00
parsed date: 2015-05-08 00:00:00.123
parsed date: 2015-05-08 00:00:01.0234
parsed date: 2015-05-08 00:00:12.00345
parsed date: 2015-05-08 00:02:03.000456
parsed date: 2015-05-08 00:20:34.0000567
parsed date: 2015-05-08 03:25:45.00000678
parsed date: 2015-05-09 10:17:36.000000789

ということで、3桁までならば正常にパースされているようです。


ぐぐってみると、下記ページを見てなるほど、となりました。

[Seasar-user:8699] Re: Timestamp型の秒以下の桁を取得するには

TimestampConverter は SimpleDateFormat を使っており,

SimpleDateFormat のパターン文字 S は「ミリ秒」なので

4 桁以上指定しても意味はありません.

ミリ秒だから本来なら3桁までのはずなので、それよりでかい桁については律儀にミリ秒を秒や分、日付に計算しなおしてくれてたのですね。


ここで渡されてくる9桁の「ミリ秒」はそういう意図のデータではないし、まあミリ秒以下のデータは不要であったため、前処理でカットしてパースするようにしました。

自分のように、DBから渡されたデータを、そのまま多桁の「S」を使ったフォーマットで読み込むと、この問題にあたりますので気をつけて。

トラックバック - http://d.hatena.ne.jp/stealthinu/20150508

2015-04-28 (Tue)

[]jquery.validationEngine.jsとautoConfirm.jsの併用 jquery.validationEngine.jsとautoConfirm.jsの併用を含むブックマーク jquery.validationEngine.jsとautoConfirm.jsの併用のブックマークコメント

javascriptである程度凝ったバリデーションをしようとすると、やはり既存ライブラリを使ったほうが良いと考え、jquery.validationEngine.jsを導入してみました。

posabsolute/jQuery-Validation-Engine

https://github.com/posabsolute/jQuery-Validation-Engine

見た目もよく、IE6以降対応で、バリデーションの種類も柔軟に設定出来ることなどからこちらにしてみました。


あと、確認画面を出すためにautoConfirm.jsというjqueryプラグインを使っていました。

autoConfirm.js - フォームの確認画面を自動生成

http://blog.material-being.com/portfolio/auto_confirm/

これは確認画面をわざわざ作らなくても、入力フォームを使って確認画面を表示してくれるものです。


で、この2つを一般的な設定で併用して使おうとすると、どちらもsubmitイベントで同時に平行して動いてしまうためうまく動きませんでした。


バリデーションが通ったら確認画面を表示する、という動作にする必要がありました。

元々は、submitするためのボタンにonclickで自前のバリデーションを実行し、trueだったときにautoConfirm.jsに回るようになっていました。

そこでjquery.validationEngine.jsも同様に動かすようにしてみました。


公式ページの使い方や、validationEngineを紹介しているエントリーではだいたい

$(document).ready(function(){
    $("#formID").validationEngine();
});

と、フォームにvalidationEngineをattachしてsubmitで自動的にvalidateが掛かるように設定していますが、「validate」というメソッドを呼ぶことでvalidateを掛けることができます。

$("#formID").validationEngine('validate');

そこで下記のように確認ボタンが押されるとvalidationEngineのvalidateを呼んで、それが通った時だけautoConfirmで確認画面に遷移する、という動作に出来ました。

<form name="editForm" class="autoConfirm">
  <input name="name" type="text" class="validate[required]">

  <button type="submit" onclick="return validate(document.editForm)">確認</button>
  <button type="button" class="autoConfirmBack" style="display:none;">戻る</button>
</form>

<script type="text/javascript" src="/js/jquery.validationEngine.js"></script>
<script type="text/javascript" src="/js/jquery.validationEngine-ja.js"></script>
<script type="text/javascript" src="/js/jquery.ba-hashchange.min.js"></script>
<script type="text/javascript" src="/js/autoConfirm.js"></script>
<script type="text/javascript">
 function validate(form) {
   if (! $(form).validationEngine('validate')) {
     return false;
   }
   return true;
 }
</script>
トラックバック - http://d.hatena.ne.jp/stealthinu/20150428

2015-04-21 (Tue)

[]MySQL WorkbenchがWin7/8でSSH経由で接続してる時selectが止まる問題 MySQL WorkbenchがWin7/8でSSH経由で接続してる時selectが止まる問題を含むブックマーク MySQL WorkbenchがWin7/8でSSH経由で接続してる時selectが止まる問題のブックマークコメント

他の人のWin7環境にMySQL Workbenchを入れてテーブルを見ようとしたところ、テーブルを見ようとselectしただけで止まってしまう(ハングしてる感じ)問題が起きました。

これ、全てのテーブルがダメなわけではなく、一部のテーブルを見ようとしただけでこの状況が起き、見れるテーブルは全く問題なく見れるのです。

止まってしまうテーブルは、limitの設定を小さくしてもやはり止まってしまいました。

また、自分のWin8.1で同じバージョン、設定で見ても問題なく見れました。ただ、一度同じような問題が発生したことがありました。(その後再現せず)


それで同じ問題にはまってる人がいないかぐぐってみたのですが、日本語の情報はなかなか無く、でも英語だともろそのものな感じの情報が見つかりました。

MySQL Bugs: #73343: Workbench Freezes on Remote SSH Server Query

MySQL Workbench hang on fetching more than some size of data - Stack Overflow


どうも

という条件でのみこの問題が発生するようで、自分の例のように同条件でも発生したりしなかったりするようです。


MySQLのmax_allowed_packet設定を大きくすることで改善したという報告もありましたが、確実ではないようです。

MySQL Workbench 6.0.9にダウングレードすると確実に改善するようです。

MySQL :: Download MySQL Workbench(6.0.9)のダウンロードページ


結局、6.0.9にダウングレードすることで対処しました。

なぜこんな謎現象が発生するのか不思議です…


(追記)

6.3.xなら治ってるかな…?と思って探してみたのですが、まだダメらしいです。

http://bugs.mysql.com/bug.php?id=74557

トラックバック - http://d.hatena.ne.jp/stealthinu/20150421

2015-04-02 (Thu)

[]javascript重複チェックとソート javascriptで重複チェックとソートを含むブックマーク javascriptで重複チェックとソートのブックマークコメント

「grape,apple,orange」のように、カンマ区切りで入力された内容を重複チェックするために、ハッシュにいれることで行いました。

例えばこんな感じです。

  input = "grape,apple,orange,apple";

  var results = {};
  var inputs = input.split(",");
  for (var i = 0; i < inputs.length; i++) {
    results[inputs[i]] = true;
  }

  for (var result in results) {
    console.log(result);
  }
grape
apple
orange

この結果をソートしたいという要望が出たため、ハッシュ results をソートしようとして results.sort() としたのですが、出来ないのですね。

あれ?出来なかったっけ?と思ったんですが、javascriptだと出来ない感じ… perlなら出来るのに。


というわけで、一度配列に突っ込み直してソートしました。

  input = "grape,apple,orange,apple";

  var results = {};
  var inputs = input.split(",");
  for (var i = 0; i < inputs.length; i++) {
    results[inputs[i]] = true;
  }

  var resultsArray = [];
  for (var result in results) {
    resultsArray.push(result);
  }
  resultsArray.sort();

  for (var i = 0; i < resultsArray.length; i++) {
    console.log(resultsArray[i]);
  }
apple
grape
orange

なんかひと手間感ありますね。


これってもっと良い方法あるのかな?

こうするといいよってのありましたら教えてください。


(追記)

@kotyさんから

input.split(',').reduce(function(prev,curr){if(prev.indexOf(curr)===-1)prev.push(curr); return prev;}, []).sort();

通りすがりさんから、ES6ならば

[...new Set(input.split(','))].sort();

といただきました。

関数型の威力をみせつけられましたねえ…

kkotyykkotyy 2015/04/02 16:42 input.split(',').reduce(function(prev,curr){if(prev.indexOf(curr)===-1)prev.push(curr); return prev;}, []).sort();

でいけました。IE8以前だと動きませんが。

stealthinustealthinu 2015/04/02 18:16 おお、すばらしい。なるほどreduceこういう感じに使うといいのか。
これ見て思ったんですが、sortしてからシュリンクすればもっと単純になりそうですね。

stealthinustealthinu 2015/04/02 18:21 …と思ったんだけどあんまりうまくいかないや。
全部と検索するんじゃなくて一つ前のと比べるだけだから単純になると思ったんだけど、別にpushする先がないとだめなのか。

kkotyykkotyy 2015/04/03 08:35 ちなみにTypeScriptだと
input.split(',').reduce((prev,curr) => {if(prev.indexOf(curr)===-1)prev.push(curr); return prev;}, []).sort();
と書けてプチハッピーです。filter/map/reduceはラムダ式と相性が良いです。

通りすがり通りすがり 2015/04/03 16:38 reduceとかを使う必要はありません。ES6なら
[...new Set(input)].sort()
だけで可能です。

stealthinustealthinu 2015/04/06 09:56 うおお、ほんとだ。なにこれすごい!
「...」になに埋めたらいいんだろ?と思ったら、これそのままで動くのですね。SetやMapはいわゆるSetやMapだろうということでわかるのですが、「...」の文法がよくわからんうえにググりにくい…
勉強してきます。

stealthinustealthinu 2015/04/06 10:20 Rest Parameters
http://odetocode.com/blogs/scott/archive/2014/08/18/features-of-es6-part-4-rest-parameters.aspx
というものでいいのでしょうか。
可変長引数をちゃんと渡せるようになる仕組み、という感じなのかな?
この手のことはnode界隈の人がよく扱ってる感じ。nodeだとブラウザのバージョンとか考えずに使えるもんね。うう、いいなあ。

通りすがり通りすがり 2015/04/08 07:15 「...」はRest/Spreadの関係で幾つかの構文が用意されています。
今回のは引数の方ではなく配列の要素として機能する方です。
また、Restは受け取り側なので、
var [a,b, ...c] = hoge;
とする時はRestですが、今回はSpreadです。
ですので「スプレッド要素」とでも呼ぶといいと思います。
全てをまとめて呼ぶときは「スプレッド構文」になると思います。
正式な名前が付いているわけではありません。

stealthinustealthinu 2015/04/08 10:48 ありがとうございます。
なるほど、newしたコレクションを「...」の場所にSpreadしてくれるのですね。
可変長引数のほうだけでイメージしてたのでわかりにくかったのですが、Spreadって言われるとわかりやすいですわ。
大変勉強になりました。ありがとうございます。

kkotyykkotyy 2015/06/29 18:04 今更コメントに気づいたんですが、ES6はすごいですね。
しかしブラウザの実装が追いついてないので、Babelってのを使うことになるんでしょうか。
http://codezine.jp/article/detail/8717

stealthinustealthinu 2015/06/30 09:51 FBとかみたいに通知飛ばないですからね… コメントでtwitterアカウント入ってたら通知飛ぶようになったらいいのに。
しかし、Babelってまた厨二心をくすぐられるネーミングですなw
ES6で書いたのをこれでコンパイルすれば良いのか。Typescriptとか使っている場合だとどうせコンパイルするんだから、それでぜんぜん構わんわけですよね。

kkotyykkotyy 2015/06/30 10:17 どこかで見かけましたが、近頃のJSは「コンパイルするもの」だそうです。なのでgulpやwebpackとかが流行っているのだろうと。

stealthinustealthinu 2015/06/30 14:21 そうなんですねえ。全然世の中の流れについていけてなくて悲しいです…

トラックバック - http://d.hatena.ne.jp/stealthinu/20150402