GitHub の issue や pullrequest でのやり取りを翻訳する (1)

恐らく単語や文法だけを覚えても実際にコミュニケーションに応用することは難しいかと思います。なので生きたやり取りを理解するように努めることで実用的な知見を取り入れることを目指します。赤字の部分は自信無し。

翻訳対象の issue
https://github.com/cakephp/cakephp/issues/3656

https://github.com/cakephp/cakephp/issues/3656#issue-35125642

メールアドレスがHTMLタグに挟まれているとき、TextHelper::autoLinkEmails()が正しく動作しません。例えばこのようなものです。lorem <p>mail@example.org</p> ipsum

https://github.com/cakephp/cakephp/issues/3656#issuecomment-45329672

<p>のあとにスペースいれたらどうなりますか?

https://github.com/cakephp/cakephp/issues/3656#issuecomment-45333289

スペースが入ると正常に動きますね。でもハードスペース &nbsp; のときは動かないです。 メールアドレスの前には常にスペースが必要みたいですね。たぶんHTMLタグは(リプレイスの対象から)除外されてるんですかね?

https://github.com/cakephp/cakephp/issues/3656#issuecomment-45340877

そうだと思います。正規表現(?<=\s|^|\() は確かにHTMLを除外して(リプレイスして)ます。

https://github.com/cakephp/cakephp/issues/3656#issuecomment-46308801

プルリクエストを作ったので閉じます。

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 は何?