Springpad から来たメールを訳す

Githubでの開発が主流となった今、英語ができないと取り残される感があるので英語の読み書きもトレーニングしていこうと思います。たまたま Springpad からサービス終了のお知らせが来たので今日はそれを翻訳することにしました。

We are very sorry to announce that Springpad will be shutting down on June 25th.
とても残念ですが、スプリングパッドは6月25日で終了することになりました。

At that point, Springpad.com will no longer be available and all online and sync features of the mobile apps will stop working.
その時点で、springpad.com は利用不可となり、モバイル向けアプリケーションの全てのオンライン、同期機能が停止します。

Read more about this announcement.
このアナウンスについて詳細はこちら。

It's our top priority to help you during this transition.
この移行期間に最優先でユーザーのサポートに取り組んでいます。

We have created multiple ways for you to take next steps with your Springpad data including a full Evernote migration option, a viewable html data backup and an importable file for other services to use.
サービスの移行ができるようにEvernote移行オプション、閲覧可能なHTML形式や他のサービスでインポートできる形式のファイルバックアップを含むいくつかの方法を用意しました。

Please visit https://springpad.com/savemystuff before June 25th to export your data.
データのエクスポートは6月25日よりも前に https://springpad.com/savemystuff から行ってください。

Thank you to our loyal users - We hope that you have enjoyed using Springpad as much as we enjoyed building it for you!
ロイヤルユーザーの皆さんありがとうございました。私達がSpringpadを開発しているのと同じくらいに楽しんで使ってもらえていたのなら幸いです。

We understand that this transition may be difficult for many of you and we will try to help as much as possible. If you have questions or need help, please visit the Springpad Shutdown FAQ
移行が難しいものであることは分かっているので可能な限りサポートしていきます。もし質問やサポートが必要なら Springpad Shutdown FAQ までどうぞ。

Android アプリケーションを JUnit でテストするための Hello World

JUnit を使ったことないので非常に苦戦していますがとりあえずテストを動かせたのでメモしておきます。Eclipse を使っています。

テスト対象の MainActivity

package com.japan;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
    public int addNumber(){
      return 1 + 2;
    }

}
  • onCreate メソッドonCreateOptionsMenu メソッドは Andorid プロジェクトを作ったのときに自動生成されたもので、今回は触っていない。追加したのは 3 を返すだけの addNumber メソッド

MainActivity をテストするためのテストコード

package com.japan.test;

import com.japan.*;
import android.test.ActivityInstrumentationTestCase2;

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity>{
  private MainActivity mActivity;

  public MainActivityTest(){
    super("com.japan", MainActivity.class);
  }
  public void testTokyo(){
    MainActivity mActivity = getActivity();
    assertEquals(3, mActivity.addNumber());
  }
}
  • 適当に android.test.ActivityInstrumentationTestCase2 というものを使っているけど、テストの用途によって使い分ける必要がある。
  • getActivity メソッドでテスト対象の MainActivity を取得しているようだ。
  • 「Run as」-> 「Android JUnit Test」でテストを実行する。「JUnit Test」を選択してもエラーが出て動かない。

Google の検索結果の絞り込み条件に 3 ヶ月 と 6 ヶ月を追加する Google Chrome 拡張機能のソースコードを Github で公開しました

大した処理はしてませんがソースコードGithub で公開しておきます。

Github
https://github.com/suzuki86/AddSearchOptions

Chromeウェブストア
https://chrome.google.com/webstore/detail/add-search-options/kaifgnoibnjldmdkkfogenbfbfgcbiao?hl=ja

作ったうえで得られた知識

DOM の変更を検知する

Google の検索結果は Javascript を使って動的に DOM を書き換えて検索結果絞り込みの部分を表示しているようでしたので MutationObserver という DOM の変更を検知してくれるオブジェクトを使いました。

window.onload = function(){
  var observer = new MutationObserver(function(mutations){
    if(!document.getElementById('qdr_m3')){
      addThreeMonth();
    }
    if(!document.getElementById('qdr_m6')){
      addSixMonth();
    }
  });
  var options = { subtree: true, childList: true, characterData: true }
  observer.observe(document.body, options);
}

満を持さずに Qiita の記事ランキングをチェックできる Android アプリ「qrank for Android」を公開しました

Qiita の人気記事をランキング形式で見たい欲が高まってきたため Android アプリをだいぶ適当な感じに作りました。もともと qrank.wbsrv.net で作っていたやつです。Android アプリのソースコードが公開されている事例があまり無かったので実験的に Github にあげてます。掲題の通り、満を持していないので継続的にメンテナンスしていきたいと思います。

Github
https://github.com/suzuki86/qrank-for-android

Google Play
https://play.google.com/store/apps/details?id=com.qrankforAndroid

TODO

  • リファクタリング
  • CI にのせる。
  • API のリクエストに Key が必要なようにする。
  • 公開しているコードでライセンス的にまずいものはないか?
  • 適当にやった Google Play の設定あってる?
  • はてブ数でソートできるようにする。
  • pull-to-refresh (ひっぱって更新)させる。
  • 最下部に到達したら追加で記事を読み込むようにする。
  • アイコンをかっこよくする。

C 言語を読み書きできないけど neovim のソースコードを読む (2)

引き続き読んでいきます。あんまり進んでいる感じがしないけど楽しいです。

ソースコードはどこから読む?

  • main.cmain 関数から実行されるはずなので、そこから順番に追っていく。

main 関数の引数

  int main(int argc, char **argv)
  • int argcchar **argv の2種類。
  • int argcコマンドライン引数の数。char **argv は引数として渡された文字列だろうけど、調べると大体でてくるのが char *argv[]になってる。ポインタのポインタを使っている理由は後から分かるはず。
  • TODO: なぜ **argv という書き方になっているのか?

変数の定義

  char_u      *fname = NULL;            /* file name from command line */
  mparm_T params;                       /* various parameters passed between
                                         * main() and other functions. */
  • コメントから察するに main 関数とその他の関数でパラメーターの受け渡しをするときに使う。

mch_early_init 関数

init_params 関数

  • main.c で定義されてる。
/*
 * Many variables are in "params" so that we can pass them to invoked
 * functions without a lot of arguments.  "argc" and "argv" are also
 * copied, so that they can be changed. */
static void init_params(mparm_T *paramp, int argc, char **argv)
{
  vim_memset(paramp, 0, sizeof(*paramp));
  paramp->argc = argc;
  paramp->argv = argv;
  paramp->want_full_screen = TRUE;
  paramp->use_debug_break_level = -1;
  paramp->window_count = -1;
}
  • たくさんあるパラメーターをまとめて扱いやすくするためかな?

vim_memset 関数

  • misc2.c で定義されてる?
#ifndef HAVE_MEMSET
void * vim_memset(ptr, c, size)
void    *ptr;
int c;
size_t size;
{
  char *p = ptr;

  while (size-- > 0)
    *p++ = c;
  return ptr;
}
#endif
  • これって定義しているコードなんだろうか?知っている関数の定義の文法じゃないような。
  • http://wisdom.sakura.ne.jp/programming/c/c33.html ← ここによると、この方法でも関数の定義ができるようだ。ただ、伝統形式と書いてあるので古いやり方らしい。括弧内に型と変数名を一緒に並べる書き方が推奨されているのなら、リファクタリングのポイントになるかも。
  • 引数として渡されたものを何かしらの処理をして返してる。(雑)

site_t 型

atexit 関数

  • C で用意されている標準関数。プログラムの実行終了時に実行する関数を予約することができる。finally 的なイメージを持った。 by http://www.c-tipsref.com/reference/stdlib/atexit.html
  • なので、プログラム終了時に vim_mem_profile_dump 関数が実行されるように予約していることになる。

vim_mem_profile_dump 関数

  • misc2.c で定義されている。

init_startuptime 関数

  • main.c で定義されている。定義内容は下記のとおり。
/*
 * Initialize global startuptime file if "--startuptime" passed as an argument.
 */
static void init_startuptime(mparm_T *paramp)
{
#ifdef STARTUPTIME
  int i;
  for (i = 1; i < paramp->argc; ++i) {
    if (STRICMP(paramp->argv[i], "--startuptime") == 0 && i + 1 < paramp->argc) {
      time_fd = mch_fopen(paramp->argv[i + 1], "a");
      TIME_MSG("--- VIM STARTING ---");
      break;
    }
  }
#endif
  starttime = time(NULL);
}
  • 引数として --startuptime が渡されたら、global startuptime file を初期化するとのこと。global startuptime file って何。
  • 今頃理解したけど、引数にある mparm_T *parampコマンドライン引数を格納してるので、paramp->argv[i] とか、paramp->argc とかでアクセスできるので便利。
  • --startuptime オプションは vim hoge --startuptime moge で起動時間を書き出すことができる。そのファイルを初期化しているということだろう。たぶん。 http://qiita.com/tachiba/items/3c1d29d74f35bdcf11a9

define は関数にも使える

  • こんな感じで。でもなんで置き換えてるんだろう?
  • TODO: なぜ define で関数名を置き換えてる?
#  define mch_fopen(n, p)       fopen((n), (p))

mb_init 関数

  • mbyte.c で宣言されている。
  • マルチバイト文字を使うための準備。
  • p_enc に格納されている値を 8bit- で始まるか?とか iso-8859- で始まるか?とか調べている。とすると p_enc にはエンコーディングの文字列が入ってそう。p_enc に値を格納している箇所を探す。
  • p_enc に値を入れているのは option.cset_init_1 関数で見つかった。後述の enc_locale 関数の返り値を格納してる。

enc_locale 関数

  • mbyte.c で定義されている。
  • たぶん OS のロケール(言語、文字コード)を取得するためのユーザー定義関数。

canonicalize とは

strncmp 関数

C にも三項演算子がある

getenv 関数

C 標準関数は大文字で表記するルール(もしくは習慣)がある?

  • そんな雰囲気。

init_var_dict 関数

  • dictionay を初期化するユーザー定義関数。
  • TODO: dictionay とは?

アロー演算子

ポインタについての分かりやすい解説を見つけた

qnx_init 関数

  • 定義場所が見つからないし、C の標準関数ではなさそう。
  • TODO: qnx_init は何?

C 言語を読み書きできないけど neovim のソースコードを読む (1)

最近 neovim というプロジェクトが話題になりました。vim をめっちゃリファクタリングしよう!っていうプロジェクトです。日頃から vim は使っているし、個人的にかなり興味のあるプロジェクトなので、なんとかして貢献できないかなーと思ってます。

でも僕は C 言語が読み書きできないので、ほとんどが C で作られている neovim ( vim もそうだけど)に貢献するためにはそれを身につける必要があります。なのでとりあえず neovim のソースを検索しまくりながら読んで活路を見出そうとしています。

どのように読み進めていくのかは決めていませんが、思いついたままの順番で読んでいきます。記事に残す粒度も適当です。

僕のスペック

  • 普段触っているのは PHPRuby で、 C を書いたことあるのは Hello World に毛が生えたくらい。
  • C はコンパイルが必要なことは知ってるけど、コンパイルがどのような工程で行われてるのかは知らない。
  • ターミナルだけでサーバーはある程度扱えるけど、コマンドそれぞれがどのような仕組みで動いているのかはあまり知らない。

configure について

  • configure は autotools というツール群によって作ることができます。

C 言語のヘッダーファイルの役割

  • ソースファイルに対して情報提供をする。
  • 理由は分からないけど、ヘッダーファイルにはクラスの宣言を書き、クラスの実装はソースコードに書く作法らしい。

lua

moon script

UINT32_t

  • 変数の型。

typedef

  • 既にあるデータ型に新しい名前をつけることができる。

struct

  • 構造体の宣言。

#ifdef

  • 条件コンパイルと呼ばれるもので、処理を分岐させることができる。

isatty 関数

  • ターミナルかどうかをチェックする標準関数。

register 指定子

  • コンパイラに対してこの指定子を付けた変数へのアクセスを最大限速くしてもらうよう宣言する。

バッファリング

  • データを逐一出力せずに一旦溜めておくこと。

拡張子が .in のファイル

  • .spec ファイルを生成するために、configure コマンドが利用するファイル。
  • configure が用いるファイルは、通常、元のファイルの拡張子に .in を追加するとのこと。

config/config.h.in

  • define がたくさん。定数の定義をしてます。

config/pathdef.c.in

  • これも define がたくさん。定数の定義をしてますが、ファイル名からして恐らくパスの設定をしているんだろう。

PHONY (Makefileに書いてあるやつ)

http://objectclub.jp/community/memorial/homepage3.nifty.com/masarl/article/gnu-make/rule.html

ターゲットとして,実際に存在しないファイル名を指定することができます.これは, 擬似ターゲットと呼んだり,ダミーターゲットと呼ばれたりしますが,統一された用語はないようです.そこで,ここでは便宜上タスクまたはタスクターゲットと呼ぶことにします(これと対比させるため,ファイルをファイルターゲットと呼ぶことにしましょう).タスクターゲットは,ある特定のファイルを作るためではなく,作業を行うコマンドとして利用したい場合に用いられます.

  • タスクの定義ってところでしょうか。

valgrind

http://www.ninxit.com/blog/2009/04/26/valgrind-%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F/

linux 環境で動く超強力なメモリデバッガー。メモリリークや、セグメンテーション違反を起こしている正確な位置を教えてくれる。

メモリデバッガーと呼ばれる類のツールのようです。

neovim.rb

  • たぶん Mac の homebrew でインストールするための設定と推測しました。

client.py

  • Python で書かれた何か。何をしているかはまだ分からない。

uncrustify.cfg

  • uncrustify は検索したところコードフォーマッター。見た目を整形するツール。そしてこのファイルはその config ファイル。

コンパイルされるまでの手順

  • make cmake これは、Makefile の cmake: clean deps で定義されていました。
cmake: clean deps
    mkdir build
    cd build && cmake $(CMAKE_FLAGS) $(CMAKE_EXTRA_FLAGS) ../
  1. build というディレクトリを作る。
  2. build ディレクトリに移動する。そして cmake コマンドを3つの引数を渡して実行する。

$(CMAKE_FLAGS) (CMAKE_EXTRA_FLAGS) ../ といった引数の意味を調べると、$() という記法は変数の展開であるから、どこかでCMAKE_FLAGSCMAKE_EXTRA_FLAGSが定義されているはず...。

CMAKE_FLAGS の定義場所

Makefile の 3 行目に書いてありました。

CMAKE_FLAGS := -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=.deps/usr -DLibUV_USE_STATIC=YES

cmake コマンド

  • make cmake を実行すると cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=.deps/usr -DLibUV_USE_STATIC=YES が実行されている。
  • cmake./configure を置き換えるものである。
  • なので cmake を実行すると Makefile が生成される。
  • CMakeLists.txtcmake を実行する時の設定ファイルである。

less のソースコードを読んでみたほうが良いかも

  • 理由は動きが vim と似てるから。less は書き込みができない vi のようなものというイメージがあるので。
  • とりあえず、less の動作は引数に渡されたファイルを読み出すのは知ってる。
  • なので、ファイルの内容を読みだして画面に表示させ続けるところとかユーザーからのキー入力で画面を操作するところとかどうやってるのかが分かるかもしれない。
  • neovim のソースコードを理解する一助になるかも。

(仮説)画面に描画する処理は恐らく screen.c

  • less のソースコードにも screen.c があった。
  • どっかのブログの記事で screen.c がうんたら書いてあったため。
  • neovim にもあった。
  • でもライセンス表記がない。つまりライブラリとして提供されているわけではなく、画面描画の処理は screen.c にするという慣習があるのかも。

続く