jQueryの関数をフックする

jQueryオブジェクトの各関数ですが、jQuery.fnに定義されています。

なので、jQueryオブジェクトの各関数をフックしたい場合には、jQuery.fnに定義されているものを差し替えます。

たとえば、showメソッドをフックして、他の処理を入れたい場合には下記のように書きます。

// 元の関数を退避
jQuery.fn._show = jQuery.fn.show; 

jQuery.fn.show = function() {
  // 追加したい処理をここに記載

  // 元の関数を呼び出し
  return jQuery.fn._show.apply(this, arguments);
};

idがcontext-menuの要素に対してshowメソッドが呼ばれた場合などは、下記のような感じで。

jQuery.fn._show = jQuery.fn.show; 

jQuery.fn.show = function() {

  if (this.attr('id') == 'context-menu') {
    // context-menuの場合には、処理を呼び出し
    appendMenu();
  }

  return jQuery.fn._show.apply(this, arguments);
};

Java7、8で入った機能で知っておいた方がよさそうなもの

Java8でコードを書くことが増えたので、Java7と8の新機能で知っておいた方がよさそうなことを、いまさらながら書き出してみます。

重要度は、自分自身が使う頻度が多かったもので判断しているので、あまりあてにならないかもしれません…
たとえば、Date and Time APIは、日付操作するようなコード書くことになった場合には、使うことになるのではと思っています。(CalendarとDateで頑張るのは苦しいので)

  • 高 (コードを書くときに頻繁に使用することになりそう)
    • try-with-resources [Java7]
      リソースの有効範囲をブロックで指定して、解放漏れを防ぐ。C#でいうusing。
    • More New I/O APIs for Java (NIO.2) [Java7]
      Path/PathsとFilesは覚えておくべき。ファイル、ディレクトリ操作が改善されている。
    • lambda [Java8]
      関数をそのままオブジェクトとして渡せるように書ける。無名クラスのインスタンスを作るような書き方をしなくて済む。
    • Stream API [Java8]
      リストなどに対して、関数型スタイルの操作を行えるように。C#でいうLinqに近い。
  • 中 (知っとくと便利な時も)
    • StandardCharsets [Java7]
      UTF-8を指定する際に、"UTF-8"と文字列を指定するのではなく、定数のStandardCharsets.UTF_8 が利用できる
    • Catching Multiple Exception [Java7]
      catchで複数の例外を指定してまとめてcatchできる。
  • 低 (そういったのがあること自体は頭の中に入れておく)
    • Optional [Java8]
      値がないかもしれないことを表現するクラスとしてOptionalが追加。
    • Date and Time API [Java8]
      日付、時間のAPIが大幅に改善/変更。
    • switchでのString対応 [Java7]
      switch文の指揮にStringが使えるようになった。
  • その他 (参考程度)
    • ダイアモンド演算子 [Java7]
      ジェネリクスを使ったクラスをインスタンス化する際に、型引数を省略可能に

JavaのparallelStream

JavaのparallelStreamについて思いつくままに。

Java8から入ったStream APIで、parallelStreamを使うと簡単に並列処理が書けますが、streamparallelStreamを使い分けるという感覚じゃなくて、並列処理を書きたい場合にparallelStreamを使うといった形で使っています。

Java8になる前は、並列処理はExecutorService周り(ForkJoinPoolとか)を使って書いていましたが、それなりにコードを書く必要があったのと、書いたコードがシンプルじゃなくなる(やりたいことに対して冗長な)感覚がありましたが、parallelStreamだと単にリストに対する操作のプロパティとして切り替えるような感じになるので、とてもすっきり書けるようになりました。

なお、並列処理を書く場合に気にしているのは、

  • オブジェクトの共有は避ける
  • オブジェクトの生成コストが高いようなものは、オブジェクトのプーリングによって生成を抑える(共有ではなく、その時点での所有者は1タスクとなるように)
  • 並列処理にすることによるコストがあるので、並列化する単位を意識する(量が多い、または1つの処理が時間がかかるなど)

といったところです。

Apache Sparkは、並列処理をサーバ跨いで分散できるようにしていますが、分散は1サーバ内での並列処理以上にオーバヘッドがあるので、ちょっとしたものならば、1サーバ上でCPUを使い切るような形で並列処理させてあげるというのも、一つの手だと思っています。 それ以上あげたければ、Spark使うといった感じで。Sparkでもリスト処理を分散するイメージなので、どちらも延長上で考えやすいのではと思っています。

社内勉強会で「30歳過ぎてもエンジニアでいるためにやったこと」というタイトルで発表しました

30歳でアウトプットを意識するようになって、エンジニアとして大きく変われたと思っているので、それについて社内勉強会で発表してきました。

www.slideshare.net

10年間これがしっかりできたかというと、かなりサボった時期もあったので、どうにか、、といった感じでしょうか。

だんだんアウトプットが減ってきているので、今日から心機一転頑張ろうと思っています。

同じ条件のStreamを繰り返し作るためのビルダーを書いてみた

同じ条件のStreamを繰り返し作るためのビルダーを書いてみました。まったく使いどころが見いだせませんが、、とりあえず書いたので晒しておきます。

Streamの中間処理の流れを定義しておいて、、

Streamer<String, Integer> streamer =
        Streamer.create(String.class)
                .map(x -> {
                    try {
                        return Integer.parseInt(x);
                    } catch (NumberFormatException e) {
                        return null;
                    }
                })
                .filter(x -> x != null)
                .sorted();

Streamの元となるデータを指定することで、Streamを作ります。同じ条件で繰り返しStreamを作れます。

streamer.build(Arrays.asList("a", "2", "1", "", "000"))
        .collect(Collectors.toList()); // -> [0, 1, 2]

streamer.build(Arrays.asList("1", "2", "-1"))
        .collect(Collectors.toList()); // -> [-1, 1, 2]

streamer.build(Arrays.asList("a"))
        .collect(Collectors.toList()); // -> []

streamer.build(Arrays.asList("100", "abc"))
        .collect(Collectors.toList()); // -> [100]

書き始めたときは、何か目的があったはずなのですが、今となっては何のためだったかわからなくなりました...

Redmine: チェックボックスのカスタムフィールドを2列で表示する (View customize plugin)

チェックボックスを2列で表示したいとのことなので、ちょっと考えてみました。

CSSでcolum-countというプロパティがあり、これを使うと段組みが簡単にできます。

View customize pluginを利用して、column-countを設定します。

設定内容

Path pattern

チケット編集系の画面を対象とします。

/issues

Code

Type:StyleSheetとして下記を設定します。

span.enumeration_cf.check_box_group {
  column-count: 2;
  -moz-column-count: 2;
  -webkit-column-count: 2;
}

追記@2016-09-07
上記はキー・バリューリストの場合ですが、リストの場合には、list_cfとなるようです。また、特定のカスタムフィールドを対象にする場合には、CSSの隣接セレクタ使って下記のように書きます。

label[for="issue_custom_field_values_1"] + span.list_cf.check_box_group {
  column-count: 2;
  -moz-column-count: 2;
  -webkit-column-count: 2;
}

結果

対応前は1列だったものが、

f:id:onozaty:20160905225251p:plain

2列で表示されるようになりました。

f:id:onozaty:20160905225259p:plain

カスタムフィールドの1列化のカスタマイズしていないときでも、チェックボックスの項目が多くて、かつ項目のラベルが短い場合には、2列表示は場所取らなくて良いかもしれませんね。

Redmine: チケット一覧の進捗率欄に値も表示する (View customize plugin)

Blogへのコメントで、チケット一覧の進捗率で数値も表示したいといったコメントをいただきました。

View customize pluginを使って以下の様なことをしようとしていますが、うまくいきません。宜しければアドバイス頂けないでしょうか?

・やりたいこと: Redmineのチケット一覧の"% Done"を数値でも表示したい。

チケット一覧では%Doneはバーで表示されます。これでは正確な数値がわからないので数値で表示したいです。 %Doneの数値が取得できるのかどうかもわかりません。

デフォルトの表示だと、こんな感じでバーでの表示になっています。

対応前

要素見てみたら、class属性として数値が記載されているので、それを使ってView customizeで対応してみます。

設定内容

Path pattern

チケット一覧を対象とします。

/issues$

Code

Type:JavaScriptとして下記を設定します。

$(function() {
  $('table.progress').each(function() {
    var target = $(this);

    // classから進捗の値を取得(progress-値 となっている)
    var match = target.attr('class').match(/progress-([0-9]+)/);
    if (!match) {
      return;
    }

    // 値を追記して表示
    var value = match[1];
    target.after($('<p>').text(value));
  });
});

対処後の画面イメージ

対応後