ミズノブログ

ミズノです。プログラミング・子育て・経年変化するもの など好きなことを雑多に書きます。

エンジニアのヘルスケアで本当に買ってよかったもの5選

エンジニアになってから十余年、日々のデスクワークのによる肩こり・腰痛・腱鞘炎が辛いです。職業病ですね。
30歳過ぎると健康管理の重要性が身にしみます。放っておくとどんどん悪化していくため、なんとか改善しようと試行錯誤の毎日です。
色々試した中で、これは本当に買ってよかった!と思えるものを紹介します。

LPN ストレッチポール®EX

LPN ストレッチポール(R)EX ネイビー 0001
LPN
売り上げランキング: 73
  • プロアスリート御用達
  • 猫背の矯正、肩甲骨まわりのストレッチに効果
  • 体幹トレーニングにも利用可能

ラグビーをやっているエンジニアの方に薦めてもらいました。
プロのアスリートも多く使われているそうです。
ポールの上に寝そべり、エクササイズをすることで正しい姿勢に矯正することができます。
寝起きに使うと、いかに体が凝り固まっているか実感できると思います。特に猫背の矯正、肩甲骨まわりのストレッチに効果があり、ググーっと伸ばすことでデスクワークで凝り固まった体をほぐすことができます。
また体幹トレーニングにも利用できるため、体を鍛えて凝りや痛みを未然に防ぐ使い方も可能です。
類似品が色々ありますが、正規品は作りがしっかりしていてヘタりもなく硬さも絶妙だったのでおすすめです。

参考サイト
ストレッチポールとは|ストレッチポール公式サイトストレッチポールとは|ストレッチポール公式サイト 
ストレッチポール®がベスト体幹ツールの理由と効果的使用法ストレッチポール®がベスト体幹ツールの理由と効果的使用法 

ドクターエア 3Dマッサージロール

  • 充電式でとにかく手軽に使える
  • 継続することで体質改善に

とあることからモニターをやることになりこの商品を知りました。
3段階のバイブレーションで凝っている箇所をほぐします。充電式でとにかく手軽につかえるので、テレビをみながらソファーで使用したりと、「買ったけど面倒になって使わない」がなく毎日使用しています。
バイブレーションだけでコリが取れるのか?と半信半疑だったのですが、筋肉を振動させることで筋膜剥がしのような効果があるそうです。足などに使うとむくみがとれ、柔軟性も高まります。
モミ玉でゴリゴリやったときのようなもみ返しがないのもメリットです。

参考サイト
3D MASSAGEROLL(マッサージロール) | DOCTOR AIR (ドクターエア)3D MASSAGEROLL(マッサージロール) | DOCTOR AIR (ドクターエア) 

PFU Happy Hacking Keyboard Professional2 墨

  • 知る人ぞ知る高級キーボード
  • キー入力のしやすさで指・手首の負担軽減

MacBookを使うようになってから薄いキーボードのせいで指が痛むようになったため、購入しました。
静電容量無接点方式のためキーがとても軽く底打ちせずに入力できるので、指や手首への負担が格段に減りました。
また矢印キーもないほどコンパクトなので、マウスへ手を伸ばす距離が最小限になり、腕への負担も少なくなります。
知る人ぞ知る高級キーボードで購入までかなり悩みましたが、本当に買ってよかったと思える一品です。

参考サイト
Happy Hacking Keyboard | PFUHappy Hacking Keyboard | PFU 
僕がHHKB(Happy Hacking Keyboard)を愛用する理由 - give IT a try僕がHHKB(Happy Hacking Keyboard)を愛用する理由 - give IT a try 

無印良品 ネッククッション

  • 昼休みの仮眠に最適
  • 寝る姿勢に合わせて形を変えられる

昼休みに15分ほど仮眠を取っているのですが、良い枕がないか探したところこれにたどり着きました。
中身がサラサラのビーズクッションになっているため、寝る姿勢に合わせて形を変えることができます。
使う前は起きた時に首が痛かったのですが、使ってからは短時間でしっかり体を休めることが出来るようになりました。

MOLDEX 耳栓お試し8種類セット

MOLDEX 耳栓お試し8種類セット
Moldex
売り上げランキング: 4,026
  • 抜群の遮音性
  • 8種セットで自分に合うものが見つかる

集中したい時、仮眠を取るときに使用するため、いろんな耳栓を試してこれにたどり着きました。
遮音性が抜群で、人の声もきちんとカットできます。(逆に声をかけられても反応できないくらいです)
大きさや柔らかさ、遮音特性などが異なる8種がセットになっているので、自分に合うものが見つけられると思います。
個人的にはカモフラージュ柄のカモプラグがおすすめです。

参考サイト
Moldex JapanMoldex Japan 
うるせぇ、MOLDEXの耳栓比較記事ぶつけんぞ!うるせぇ、MOLDEXの耳栓比較記事ぶつけんぞ! 

すぐできる!Java100本ノックをSlackに自動投稿するBot

先日、JJUG CCC 2016 Fallに参加してきました。 その中でJava100本ノックが紹介されており、面白そうだから社内でもやってみようかという話になりました。 Slackに問題を自動投稿するBotスプレッドシートとGASで作ってみたので、よければ参考にしてみてください。

手順

1.問題番号を保存するスプレッドシート作成

Java100本ノックSlackBot_-_Google_スプレッドシート.png

2.スクリプトエディタを開く

スプレッドシートのメニューから「ツール」→「スクリプトエディタ」を選択します。

3.GASにSlackAppライブラリを導入する

スクリプトエディタのメニューから「リソース」→「ライブラリ」を選択し、以下のLibrary Keyを入力します。

SlackAppのLibrary Key → M3W5Ut3Q39AaIwLquryEPMwV62A3znfOO

4.Slackのトークンを発行

こちらの記事を参考に、Slackのトークンを発行します。

5.コード作成

スクリプトエディタに以下のコードを貼り付けます。 TOKEN定数は上記で取得したトークンに置き換えてください。

var URL = "https://github.com/JustSystems/java-100practices/tree/master/contents/";
var TOKEN = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // 取得したトークンを貼り付け

function main() {
  // 平日のみ投稿
  var today = new Date();
  if(isJapaneseHoliday(today) || today.getDay() == 0 ||today.getDay() == 6){return;} 
  
  var qNumRange = SpreadsheetApp.getActiveSheet().getRange(1, 2);
  var qNum = qNumRange.getValue();
  postSlackMessage(qNum);
  
  // 問題インクリメント
  qNum++;
  if(qNum > 100){ qNum = 1;}
  qNumRange.setValue(qNum);
}


function postSlackMessage(qNum) {
  var slackApp = SlackApp.create(TOKEN); //SlackApp インスタンスの取得
 
  var options = {
    channelId: "#java100knock",
    userName: "Java100本ノックBot",
    message: "今日の問題はこちら!\n" + 
             URL + ('000' + qNum).slice( -3 ) // 問題番号0埋め         
  };
 
  slackApp.postMessage(options.channelId, options.message, {username: options.userName});
}

function isJapaneseHoliday(date) {
  var year = date.getFullYear();
  var month = date.getMonth();
  var day = date.getDate();
  
  var startDate = new Date();
  startDate.setFullYear(year, month-1, day);
  startDate.setHours(0, 0, 0, 0);

  var endDate = new Date();
  endDate.setFullYear(year, month-1, day);
  endDate.setHours(23, 59, 59, 999);

  var cal = CalendarApp.getCalendarById("ja.japanese#holiday@group.v.calendar.google.com");
  var holidays =  cal.getEvents(startDate, endDate);

  return holidays.length != 0;
}

この状態でmainメソッドを実行すると、Slackのjava100knockチャンネルに問題が投稿されます。

6.起動トリガーを設定

スクリプトエディタのトリガーアイコン(時計のマーク)より、トリガーを設定します。 Java100Knock.png

この設定で毎朝8~9時に問題が自動投稿されます。(ソース内で平日のみ投稿するように制御しています)

投稿された問題は以下のような感じになります。 Slack_-_Paygent.png

参考

Scala入門時に役立つ情報まとめ

はじめに

Scalaの勉強を始めた時にJavaRubyと比べると情報量が少なく苦戦したので、今まで調べたことや経験者から聞いた情報などをまとめてみようと思います。
私自身まだまだ初心者ですが、これからScalaやってみようかなと思っている人の参考になれば幸いです。

WEBサイトで勉強する

ScalaのインストールやHelloWorldなどは検索するとすぐ見つかるので割愛します。
Scala特有の記法や概念などを勉強するのに以下のサイトが参考になりました。

技術系

読み物系

勉強会・イベントに参加する

技術書選びやネットでの勉強が意外と苦戦したので、勉強会を探して経験者に直接聞く作戦に切り替えました。ただ勉強会も他の言語に比べると少ないです。
関東で唯一?定期開催している芸者東京エンターテインメント社の「Scala勉強会in東京」にお邪魔させていただきました。
結果として作戦は大成功で、有益な情報がたくさん聞けました。可能な限り通いたいと思います。
またScalaをテーマにした日本最大級のカンファレンス「ScalaMatsuri」が2016年1月30、31日に開催されるので参加してみようと思います。

書籍で勉強する

通称コップ本と呼ばれる「Scalaスケーラブルプログラミング第2版 (2016/09/20に第3版が出版されました!)」がいちばん有名です。ただし全35章、700ページ超えと、初心者が読み切るにはそれなりの覚悟が必要です。苦笑

業務でScala使っている方に伺ったところ、普段は「Scala逆引きレシピ」で調べて、深く知りたい箇所をコップ本で勉強するのが良いのでは。との回答でした。
個人的には「関数プログラミング実践入門」「Javaによる関数型プログラミング」を読んでいたおかげで比較的すんなり頭に入ってきた感があるので、関数型プログラミングを全く知らない方は合わせて読むと良いかも知れません。

※ 参考:Scalaを学ぶためのScala本の読み進め方 (10冊)

問題を解く

とにかくコード書くのが上達の近道とのことで、別言語技術書のサンプルソースScalaに書き直す、などやったりするそうです。
最近はオンラインでプログラミングの問題を解くことができるので、簡単なレベルのものからScalaで書いています。プロコン系は開催日が指定されていることが多いので、自分のペースで進められる「Paiza」「AOJ」あたりがオススメです。
また「AtCoder」は過去問について他ユーザの回答を閲覧できるので、自力で解いた後に他の回答を見て良いところを盗む、といった使い方ができます。

Scala界の著名エンジニアを追う

Scalaの最新情報をキャッチアップする方法について勉強会で相談したところ、口を揃えて「吉田さんをフォローしろ」と言われました。
てっきりどこかのサイトを教えてもらえるものだと思っていたので、エンジニアをフォローするというアプローチはかなり新鮮でした。
私が参考にさせてもらっているエンジニアの方たちを挙げさせてもらいます。(50音順)

瀬良 和弘さん

エムスリー社ソフトウェアエンジニア。 ScalikeJDBC、Skinny Framework など Scala OSS プロジェクトリード。 Scalatra、json4s、Scalate のメンテナ。

竹添 直樹さん

ビズリーチ社チーフアーキテクト。 Scala逆引きレシピ著者、GitBucketファウンダー。

中村 学さん(がくぞさん)

株式会社Tech to Value 代表取締役。 Japan Scala Association理事。

水島 宏太さん

ドワンゴプログラマ。 Japan Scala Association代表理事。

Kenji Yoshidaさん

scalazとsbtとargonautとscalikejdbcのコミッター。

フレームワーク関連

WEBアプリフレームワーク

Play Framework」がデファクトスタンダードと言ってよさそうです。執筆時点で安定版である2.4系の情報が意外と少ないので、古い記事は公式の移行ガイドなどを見ながら読み替えをする必要になるかも知れません。ビズリーチ社のハンズオンは2.3系、2.4系が用意されているのでとても参考になりました。
シンプルでSinatraライクなWebフレームワークとして「Scalatra」も人気があるようです。

DBアクセスライブラリ

SlickScalikeJDBCが二大勢力のようです。SlickはPlayFrameworkの標準ライブラリになりました。
ScalikeJDBCは前述のエンジニアの方たちが作っているので、本当に困ったら直接聞けるというメリットがあります。(と勉強会で教わりました。笑)
私個人はScalikeJDBCを勉強し始めた段階なので、それぞれの良さがわかった頃に改めてまとめたいと思います。

※ 参考:Slick vs ScalikeJDBC

その他

scalazを使うエンジニアを業界では「Z戦士」と呼ぶそうです。笑

開発環境関連

IntelliJ IDEA

PlayFrameworkの勉強時、始めはEclipseにScalaIDEというプラグインを入れて使っていたのですが、動作が不安定&重いのでIntelliJ IDEAに乗り換えてみました。まだ使い始めなので慣れないですが、サクサク動いておすすめです。

ATOM

最近注目のテキストエディタATOMを使って開発環境を整えることもできるそうです。IDEを使うには大げさすぎる時など状況によって使い分けるといいかもしれません。 * AtomでのScala開発環境 - たけぞう瀕死ブログ

小ネタ

REPLでシンタックスハイライト

  • Scala 2.11.4より、ターミナルで"scala -Dscala.color"と入力してREPLを起動するとちょっとだけ(REPL結果の変数と型だけ)カラー表示となる。

Java8 逆引き Stream API

はじめに

Java8の新機能、Stream APIを使い始めてコーディングが格段に楽になりました。 備忘録的にサンプルコードを書き出してみました。少しずつ追加していく予定です。 Javaは使ったことあるけどラムダ式やStream APIはよく知らないという方は、参考にしてみてください。 バリバリ使っている方は、こんな使い方もあるよ!と教えていただけると嬉しいです。

ちなみにオライリー社のJavaによる関数型プログラミング ―Java 8ラムダ式とStreamがとても参考になりました。

【前提条件】Stream APIの説明に使用するオブジェクト

public class Person {
  private String name;
  private int age;
  private List<Person> children;

  public Person(String name){/*...*/}
  public Person(String name, int age){/*...*/}
  public Person(String name, int age, Person... children){/*...*/}
  
  @Override
  public String toString() {/* name(age) [children...] */}
  
  // getter, setter...
}

コレクション、配列、MapをStreamクラスに変換(Arrays#stream,Stream#of)

  // コレクション
  List<String> list = new ArrayList<>();
  Stream<String> listStream = list.stream();

  // 配列
  String[] ary = new String[] {"AA","BB","CC"};
  Stream<String> aryStream1 = Arrays.stream(ary);
  Stream<String> aryStream2 = Stream.of(ary);

  // MAP
  Map<String,String> map = new HashMap<>();
  Stream<Entry<String, String>> mapStream = map.entrySet().stream();

メソッド参照・コンストラクタ参照(Class::method)

  String[] names = new String[] {"Tom","Bob","Alice"};

    Stream.of(names)
      // コンストラクタ参照
      .map(Person::new) // name -> new Person(name)
      // メソッド参照
      .forEach(System.out::println); // person -> System.out.println(person)
      // Tom(0)
      // Bob(0)
      // Alice(0)

Personリストからnameリスト作成(Stream#collect,Collectors#toList)

  List<Person> persons = new ArrayList<>();
  persons.add(new Person("Tom",  21));
  persons.add(new Person("Bob",  25));
  persons.add(new Person("Alice",19));

  List<String> nameList =
    persons.stream()
      .map(Person::getName)
      .collect(Collectors.toList());
 
  nameList.steram().forEach(System.out::println);  
    // "Tom"
    // "Bob"
    // "Alice"

PersonリストからnameのCSV作成(Stream#collect,Collectors#joining)

  List<Person> persons = new ArrayList<>();
  persons.add(new Person("Tom",  21));
  persons.add(new Person("Bob",  25));
  persons.add(new Person("Alice",19));

  String nameCSV =
    persons.stream()
      .map(p -> String.format("\"%s\"", p.getName()))
      .collect(Collectors.joining(","));

  System.out.println(nameCSV);
  // "Tom","Bob","Alice"

Personリストからageの重複なしリスト作成(Stream#distinct)

  List<Person> persons = new ArrayList<>();
  persons.add(new Person("Tom",  21));
  persons.add(new Person("Bob",  25));
  persons.add(new Person("Alice",19));
  persons.add(new Person("Mike", 19));

  List<Integer> ageDistinctList =
    persons.stream()
      .map(Person::getAge)
      .distinct()
      .collect(Collectors.toList());
    
  ageDistinctList.stream().forEach(System.out::println);
  // 21
  // 25
  // 19

Personリストをage順にソート(Stream#sorted,Comparator#comparingInt)

  List<Person> persons = new ArrayList<>();
  persons.add(new Person("Tom",  21));
  persons.add(new Person("Bob",  25));
  persons.add(new Person("Alice",19));

  persons.stream()
    .sorted(Comparator.comparingInt(Person::getAge))
    .forEach(System.out::println);
    // Alice(19)
    // Tom(21)
    // Bob(25)
    

Personリストをname頭文字でグループ化(Comparator#groupingBy)

  List<Person> persons = new ArrayList<>();
  persons.add(new Person("Tom",  21));
  persons.add(new Person("John", 18));
  persons.add(new Person("Jack", 19));

  Map<Object,List<Person>> nameIndex =
    persons.stream()
      .collect(Collectors.groupingBy(p -> p.getName().charAt(0)));

    System.out.println(nameIndex);
    // {J=[John(18), Jack(19)], T=[Tom(21)]}

Personリストからchildrenリスト作成(Stream#flatMap)

  List<Person> persons = new ArrayList<>();
  persons.add(new Person("Tom", 21,
                  new Person("Tomas", 1), 
                  new Person("Tommy", 0)));
  persons.add(new Person("Bob", 25,
                  new Person("Bobby", 2)));
  persons.add(new Person("Alice", 19));

  persons.stream()
    .flatMap(person -> person.getChildren().stream())
    .forEach(System.out::println);
    // Tomas(1)
    // Tommy(0)
    // Bobby(2)    

try-with-resourcesでリソース解放されないパターン

はじめに

Java7から"try-with-resources"構文が追加されました。 ファイルやDBアクセスしたあとのリソース解放を自動で行ってくれる大変便利な機能で、解放し忘れをなくし、コードをすっきりさせることができます。 ただし、書き方によってリソースが解放されないパターンがあったので紹介します。

具体的には以下のような場合です。 リソース解放の対象クラスをネストさせてインスタンス生成した場合、コンストラクタで例外が発生するとリソース解放されません。

File file = new File("out.txt");
// PrintWriterがインスタンス生成に失敗すると、BufferedWriter・FileWriterが解放されない
try(PrintWriter pw = 
        new PrintWriter(new BufferedWriter(new FileWriter(file)));) {
    // 処理
}
// ・・・

検証

各Writerクラスにログを仕込み、どのような動作をするか検証してみました。

public class Test {
    public static void main(String[] args) {

        File file = new File("out.txt");
        try (PrintWriter pw = 
                new PrintWriterWrapper(
                new BufferedWriterWrapper(
                new FileWriterWrapper(file)));) {
            System.out.println("func");
        } catch (Exception e) {
            System.out.println("catch:" + e);
        } finally {
            System.out.println("finally");
        }
    }

    // 以下、ログを追加したラッパークラス

    public static class PrintWriterWrapper extends PrintWriter {

        public PrintWriterWrapper(Writer out) {
            super(out);
            System.out.println("new PrintWriter");
        }

        @Override
        public void close() {
            System.out.println("close PrintWriter");
            super.close();
        }
    }

    public static class BufferedWriterWrapper extends BufferedWriter {

        public BufferedWriterWrapper(Writer out) {
            super(out);
            System.out.println("new BufferedWriter");
            throw new RuntimeException();
        }
        @Override
        public void close() throws IOException {
            System.out.println("close BufferedWriter");
            super.close();
        }
    }

    public static class FileWriterWrapper extends FileWriter {

        public FileWriterWrapper(File file) throws IOException {
            super(file);
            System.out.println("new FileWriter");
        }

        @Override
        public void close() throws IOException {
            System.out.println("close FileWriter");
            super.close();
        }
    }
}

処理が正常終了する場合、作成したインスタンスを逆順でリソース解放(closeメソッド実行)しています。

// ・・・
// ネストでインスタンス生成する
try (PrintWriter pw = 
        new PrintWriterWrapper(
        new BufferedWriterWrapper(
        new FileWriterWrapper(file)));) {
    System.out.println("func");
}
// ・・・

// 実行結果(close()が実行されている)
// new FileWriter
// new BufferedWriter
// new PrintWriter
// func
// close PrintWriter
// close BufferedWriter
// close FileWriter
// finally

ただしコンストラクタで例外が発生した場合、内包するインスタンスに対するリソース解放がされません。

// ・・・
// ネストでインスタンス生成する
try (PrintWriter pw = 
    new PrintWriterWrapper(
    new BufferedWriterWrapper(
    new FileWriterWrapper(file)));) {
  System.out.println("func");
}

// ・・・

// PrintWriterWrapperのコンストラクタで例外発生させる
public PrintWriterWrapper(Writer out) {
    super(out);
    System.out.println("ERROR!! new PrintWriter");
    thorow new RuntimeException();
} // ・・・

// 実行結果(close()が実行されない)
// new FileWriter
// new BufferedWriter
// ERROR!! new PrintWriter
// catch:java.lang.RuntimeException
// finally

ポイントは以下の2点です。

  • "try句で変数として宣言されたインスタンス"が自動リソース解放の対象となる
  • try句でインスタンス生成する際、コンストラクタで例外が発生した場合はcloseメソッドが実行されない

検証1では、変数pwのcloseメソッドが実行され、内包するBufferedWriter、FileWriterを連鎖的にcloseしています。 検証2では変数pwのcloseメソッドが実行されず、内包するインスタンスも自動リソース解放の対象となっていないためそのまま残ってしまいます。

解決法:ネストせず個別に変数定義する

結論として、コンストラクタで例外が発生しないことが明白である場合以外は個別に変数定義するのが良さそうです。 以下の例ではPrintWriterのインスタンス生成に失敗した場合もBufferedWriter、FileWriterのcloseメソッドが実行されています。 (FileWriterのcloseメソッドが2回実行されているのは、BufferedWriterのcloseメソッドから連鎖的に実行されたのと変数fwとして宣言したため自動リソース解放の対象となっているためです。)

// ・・・
// 個別にフィールドを宣言し、それぞれインスタンス生成する
try ( FileWriter fw = new FileWriterWrapper(file);
    BufferedWriter bw = new BufferedWriterWrapper(fw);
    PrintWriter pw = new PrintWriterWrapper(bw);) {
  System.out.println("func");
}

// ・・・

// PrintWriterWrapperのコンストラクタで例外発生させる
public PrintWriterWrapper(Writer out) {
    super(out);
    System.out.println("ERROR!! new PrintWriter");
    thorow new RuntimeException();
}
// ・・・

// 実行結果(close()が実行されている)
// new FileWriter
// new BufferedWriter
// ERROR!! new PrintWriter
// close BufferedWriter
// close FileWriter
// close FileWriter
// catch:java.lang.RuntimeException
// finally

エンジニアの情報収集法まとめ

※二重管理になってしまうため、エンジニアの情報収集法まとめ - Qiitaに情報集約することにしました。 今後はQiita記事を参照してください。こちらの記事は情報更新しません。

はじめに

プログラミング系の時事ネタは能動的に情報収集しないと入ってこないのですが、若手だった頃はどうやって情報を仕入れればよいのかさっぱり分かりませんでした。
情報収集のコツを掴んでからパッと視界が開けた経験があるので、特に新米エンジニアの方は参考にしてみてください。

ニュースアプリ

GunosySmartNewsなど色々試しましたが「はてなブックマーク」がプログラミング系記事多めでした。
通勤時間などに流し読みして、気になるものは深く調べると良いです。

はてなブックマーク
はてなブックマーク - 人気エントリー - テクノロジーはてなブックマーク - 人気エントリー - テクノロジー 

ITニュース

Webサイト

TechCrunch Japan
TechCrunch Japan - 最新のテクノロジーとスタートアップ・Webに関するニュースを配信するブログメディアTechCrunch Japan - 最新のテクノロジーとスタートアップ・Webに関するニュースを配信するブログメディア
POSTD
POSTD | プログラミングの話題を翻訳して届けるエンジニアのためのニュースメディアPOSTD | プログラミングの話題を翻訳して届けるエンジニアのためのニュースメディア
CodeZine(コードジン)
CodeZine(コードジン)CodeZine(コードジン)
CodeIQ MAGAZINE
CodeIQ MAGAZINE|エンジニアのためのWebマガジンCodeIQ MAGAZINE|エンジニアのためのWebマガジン
SELECK [セレック]
SELECK [セレック]|企業の隠れた知が集まるビジネスライブラリSELECK [セレック]|企業の隠れた知が集まるビジネスライブラリ
UX MILK
UX MILK | クリエイターのためのUXメディアUX MILK | クリエイターのためのUXメディア
geechs magazine(ギークスマガジン)
フリーランスエンジニアの「イマ」を知る | geechs magazine(ギークスマガジン)フリーランスエンジニアの「イマ」を知る | geechs magazine(ギークスマガジン) 

メールマガジン

Frontend Weekly
Frontend WeeklyFrontend Weekly 

Web系企業・エンジニア技術ブログ

クックパッド開発者ブログ
クックパッド開発者ブログクックパッド開発者ブログ 
クラスメソッド株式会社ブログ | Developers.IO
AWS/iOS技術者の必読メディア:クラスメソッド株式会社ブログ | Developers.IOAWS/iOS技術者の必読メディア:クラスメソッド株式会社ブログ | Developers.IO 
Hatena Developer Blog
Hatena Developer BlogHatena Developer Blog 
サイボウズ
サイボウズ式 | 「新しい価値を生み出すチーム」のための、コラボレーションとITの情報サイトサイボウズ式 | 「新しい価値を生み出すチーム」のための、コラボレーションとITの情報サイト 
さくらのナレッジ
さくらのナレッジ | ITエンジニアに役立つ情報&おもしろネタを、 ホスティング・データセンター業界の最前線から 全力でシェア!さくらのナレッジ | ITエンジニアに役立つ情報&おもしろネタを、 ホスティング・データセンター業界の最前線から 全力でシェア! 
Social Change! ソニックガーデン SonicGarden 倉貫義人のブログ
Social Change! ソニックガーデン SonicGarden 倉貫義人のブログSocial Change! ソニックガーデン SonicGarden 倉貫義人のブログ 

技術情報共有サービス

Qiita
Qiita - プログラマの技術情報共有サービスQiita - プログラマの技術情報共有サービス 

学習系Webサイト

ドットインストール

動画でプログラミング学習できるサイト。様々なプログラミング言語の入門向け情報がまとめられています。新人の学習はもちろん、新しい言語に挑戦するときの最初の一歩にも最適。

ドットインストール - 3分動画でマスターする初心者向けプログラミング学習サイトドットインストール - 3分動画でマスターする初心者向けプログラミング学習サイト 
ひしだま's 技術メモページ

個人運営のWebサイト。情報量が多く、特にJavaScalaの勉強でお世話になっています。

ひしだまのコンピューター関連技術メモ(Hishidama's Programming MemoPage)ひしだまのコンピューター関連技術メモ(Hishidama's Programming MemoPage) 

質問系Webサイト

エンジニア版Yahoo知恵袋のようなQ&Aサービス。開発中一番お世話になります。

StackOverFlow

おそらく世界で一番有名なQ&Aサイト。日本語版もできました。

Stack OverflowStack Overflow 
Teratail

最近話題の日本版StackOverFlow。レバレジーズ社のサービス。

teratail【テラテイル】|思考するエンジニアのためのQAプラットフォームteratail【テラテイル】|思考するエンジニアのためのQAプラットフォーム 

スライド共有サイト

プレゼン資料の共有サービス。登壇者が発表後アップしていることが多いので復習しましょう。

SlideShare
Share and Discover Knowledge on LinkedIn SlideShareShare and Discover Knowledge on LinkedIn SlideShare 
SpeakerDack
Speaker Deck - Share Presentations without the MessSpeaker Deck - Share Presentations without the Mess 

技術系イベント検索サイト

特にdots.がオススメ。エンジニア向けイベント検索に特化していて、気になる技術にチェックを入れておくと関連イベントをメール通知してくれます。

dots.
dots. [ドッツ] - IT勉強会・セミナーなどのイベント情報サイトdots. [ドッツ] - IT勉強会・セミナーなどのイベント情報サイト 
connpass
connpass - エンジニアをつなぐIT勉強会支援プラットフォームconnpass - エンジニアをつなぐIT勉強会支援プラットフォーム 
ATND
イベント開催支援ツール アテンド : ATNDイベント開催支援ツール アテンド : ATND 
Doorkeeper

セミナー・勉強会・イベント管理ツール | Doorkeeper
セミナー・勉強会・イベント管理ツール | Doorkeeper  

勉強会・イベントスペース

最近エンジニア向けのイベントスペースが増えてきました。渋谷に集中しているようです。都心勤務の方はぜひ。

ヒカ☆ラボ(渋谷ヒカリエ)

レバレジーズ社がエンジニア、クリエイターの方のために無料で開催する勉強会。

ヒカラボとは | ヒカラボヒカラボとは | ヒカラボ 
21Cafe<ニイイチカフェ>(渋谷区道玄坂)

geechs社が運営する、エンジニア&デザイナーのための無料イベントスペース。


    ABOUT|エンジニア&デザイナーのための無料イベントスペース 21cafe<ニイイチカフェ>    ABOUT|エンジニア&デザイナーのための無料イベントスペース 21cafe<ニイイチカフェ>  
dots. イベントスペース(渋谷区宇田川町)

イベント情報検索サービス「dots.」のイベントスペース。

dots. [ドッツ] - IT勉強会・セミナーなどのイベント情報サイトdots. [ドッツ] - IT勉強会・セミナーなどのイベント情報サイト 

コミュニティ

カンファレンス

技術系雑誌

そのまま業務で使えるような特集が多く組まれており、得た知識を実戦投入しやすいのが魅力です。 雑誌で幅広く情報をキャッチして、気になる技術は技術書などで深く勉強する、などすると良いと思います。

ポッドキャスト

  • Rebuild.fm :
    宮川達彦さんがMCを務める、おそらく日本で一番有名なテック系ポッドキャスト。毎回ゲストを迎え、ITニュース、技術、ガジェットなどの最新時事ネタからアニメまで幅広いテーマを扱います。伊藤直也さんゲスト回のエモい話は必聴。

  • mozaic.fm :
    Rebuild.fmと比べ、より技術に特化したド直球のポッドキャストJxckさんがMCを務めています。更新は少なめですが、何度もじっくり聞き直したくなる濃い内容です。

  • codelunch.fm :
    「エンジニアがランチの時に話すような技術ネタ」がコンセプトのポッドキャスト。なかでも和田卓人(@t_wada)さんがPaworAssertについて語った第16,17回は必聴です。

Slack公開グループ

著名エンジニア

技術書や技術系ブログの著者、技術系イベントの登壇者など、気になった人をフォローすると新鮮な情報が入ってきて勉強になります。
情報が増えてきたので別記事に切り出しました。こちらを参照してください。

nesheep5.hatenablog.com

これからrubyを始める人のコードエディタ/IDE選び

ruby/railsを勉強するにあたり、悩んだのが開発環境でした。

Javaの場合Eclipseというデファクトスタンダードがあったのですが、どうやらruby/railsはそうではないらしく。。

ruby/rails開発環境の主な選択肢

ネットで調べてみると、以下をオススメしていることが多かったです。

コードエディタ
統合開発環境(IDE)
※参考サイト・書籍

Vimは学習・環境構築に時間がかかる

「なになにruby開発者はIDEよりVimが普通?なにそれプロっぽい」と、意気揚々とVimを選択したところ、見事に撃沈。。苦笑
Vimはそれ自体が独特な操作方法のため、学習コストがかかります。
加えて、

などが必要で、railsよりむしろVimの勉強に時間割くことになりました。苦笑

Javaエンジニアなら、まずAptana

元々Javaで開発を行っているのであれば、EclipseベースのAptanaが扱いやすいと思います。 統合開発環境のためインストールするだけで環境が整い、操作方法も大体見当がつくのですぐruby/railsの勉強に入れます。

いずれはVimmer

ただしハイレベルプログラマほどVimEmacsの利用者が多いようです。 理由としては、

  • モードという概念により、単純にタイプ数が減りコーディングが速い
  • カスタマイズ性が高く、自分好みにセッティング可能
  • プラグイン開発が活発で、必要な機能は大体用意されている
  • 欲しい機能がなければ、自分で作成可能

使いこなせばこちらの方が開発が捗るようです。

参考:なぜ、IDEじゃなくてVimを使うか。 - Qiita

Aptanaスタート→徐々にVim

Aptanarailsを一通り勉強→時間がある時に少しずつVimを勉強→徐々にVimに移行

が一番効率いいんじゃないかなと思います。参考になれば幸いです。 (ちなみに現在進行形です。Vimmer目指して奮闘中。)

vim:"diw"は "d + i + w" に分けて考える

「vimtutor」で基本操作を勉強したのち、最初につまづいたのが

「"diw" = 単語ごとに削除」

でした。コマンドから意味が推測出来ない。。

色々調べてみたところ、"d"を「operator」、"iw"を「text-object」と言うそうです。勉強したついでに整理してみました。

コマンド入力ルール

"回数" + "操作" + "範囲" + "単位" の組み合わせで決定する。

  • "回数"は省略可能。(省略した場合は"1"回)
  • "範囲"は"操作"によっては省略可能。(省略した場合は"a"選択と同様)

上記ルールに則って、操作、範囲、単位の引き出しを増やしていけばOKのようです。

詳しくは以下を参照。

操作(operator)

ざっくりと代表的なものだけ載せておきます。 | コマンド | 説明 | |:-------:|:----------| | d | 削除 (delete) | | y | コピー (yank) | | p | 貼付け (paste) | | c | 削除+挿入(change) |

範囲

コマンド 説明 詳細
a 単一 (冠詞の'a') 区切り文字を含める。
i 内側 (inner) 区切り文字を含めない。

おそらく一番分かりにくいのがココです。
区切り文字とは、"単位"を区切る文字のことです。
"w"なら空白文字、"t"ならHTMLタグなど。

例1:「this is a pan.」に対する適用範囲(カーソルが先頭"t"に当たった状態)

  • "aw" は「this 」 (空白文字(半角スペース)を含める)
  • "iw" は「this」 (空白文字(半角スペース)を含めない)

例2:「<p>this is a pan.</p>」に対する適用範囲(カーソルが先頭"<"に当たった状態)

  • "at" は「<p>this is a pan.</p>」 (HTMLタグを含める)
  • "it" は「this is a pan.」 (HTMLタグを含めない)

単位

文字

コマンド 説明 詳細
w 単語 (word) アルファベット、数字、アンダースコアの連続した文字
※詳細は「:help word」参照
W 単語 (WORD) word + 非空白文字(括弧や引用符など)で連続した文字
※詳細は「:help WORD」参照
s 文 (sentence) '.', '!', '?' で終わり、その後に行末かスペースもしくはタブが続く文字列
※詳細は「:help sentence」参照
p 段落 (paragraph) 空行で囲われた文節の塊り
※詳細は「:help paragraph」参照
t HTML,XMLタグ (tag)

ブロック

コマンド 説明
b または ( または ) ( )ブロック(block)
B または { または } { }ブロック(Block)
[ または ] [ ]ブロック
< または > < >ブロック

引用符

コマンド 説明
' シングルクォーテーション
" ダブルクォーテーション
` バッククォート

具体例

あとは上記内容を組み合わせればOKです。
タイトルにも挙げた"diw"は

"diw" = (delete inner word) =単語ごとに削除

と分かります。

「this is a pan.」(カーソルが先頭"t"に当たった状態)で"diw"を実行すると、

"iw"(inner word) で指定した適用範囲「this」を"d"(削除)するので

「 is a pen.」

という結果になります。

参考サイト・書籍