gitブランチの名前の付け方2

以前、gitブランチの名前の付け方について紹介したことがあります。

gitのブランチの名前の付け方

実際に定着している名前は、次の4つです。
プロジェクトによっては、master、developだけで済ましてしまうこともあります。

(1) master
製品ブランチ

(2) develop
リリース前の確認用ブランチ

(3) personals/aoki/develop
開発者ごとの作業ブランチです。developからブランチします。

(4) personals/aoki/1
一時的な作業ブランチです。最後の数字はチケット番号です。personals/aoki/developですでに作業中のとき、別チケットの作業をしたいときの一時的なブランチです。developからブランチします。コミットして、developへマージしたら、すぐに削除します。

今は使わなくなった方法も紹介しましょう。

(ボツ1) ブランチ名に機能の名称をつける

チケットにする前の実験的な機能を試したいときに、ブランチ名に機能の名称をつけたことがあります。

例えば、
develop_camera
develop_news

コレという名前を考えるのが面倒でした。チケットを起こしてチケット番号をつけたほうが楽です。そもそも実験的なので放置することも多く、何をやっていたかを覚えていないこともあります。チケットにアイデアをメモしておくと、何をやっていたか思い出しやすくなります。

(ボツ2) 複数の作業ブランチ

gitは簡単にブランチ作成できることもあって、
personals/aoki/1
personals/aoki/2
personals/aoki/3
といったように、複数の作業ブランチを作成していたことがあります。

confictの解決も手間ですが、conflictがなかったとしても、マージ操作自体が面倒でした。

例えば、personals/aoki/1の作業が一段落したら、
personals/aoki/1からdevelopへマージ
developからpersonals/aoki/2へマージ
developからpersonals/aoki/3へマージ
する必要があります。

さらに、他の開発者がdevelopへpushしたら、
developからpersonals/aoki/1へマージ
developからpersonals/aoki/2へマージ
developからpersonals/aoki/3へマージ
する必要があります。

このようにブランチ切り替えとマージ操作が多くて面倒だったので、ブランチを作りすぎるのもどうかと感じました。

「継続的デリバリー」という本では、複数人で開発していても、メインブランチ1本を推奨しています。ブランチ間のマージが面倒になるため、またメイン以外のブランチは自動テストしないことが多いためです。また、少なくても1日に1回、たいていは1日に数回コミットすることも推奨しています。

android F-03G NFCの項目がグレー表示でチェックを付けることができない

FujitsuのタブレットF-03Gを2台持っています。

F-03GでNFCを使うには、設定>便利機能>NFCにチェックを付けて、NFCを有効にします。

1台のF-03Gは問題なくNFCを使うことができました。

ところが、もう1台のF-03Gは、設定>便利機能>NFCの項目がグレー表示になっていて、チェックを付けることができません。

なぜ?と思って調べたところ、USB充電しているとグレー表示になるようです。グレー表示のF-03Gは、USB充電ケーブルをつないだままでした。USB充電ケーブルをはずしたら、チェックを付けることができ、NFCを読み込むことができました。

参考URL
価格.com – 『NFCがONにできない』富士通 ARROWS Tab F-02F docomo
http://bbs.kakaku.com/bbs/K0000584870/SortID=17118914/

デバッガでトレースしやすい書き方

IDEのデバッガには、1行づつの「ステップ」、関数の中へ入る「ステップイン」、関数から戻る「ステップオーバー」、ローカル変数やメンバー変数の値を表示する機能があります。式の一部分を指定して評価する機能もありますが、その操作をする必要があります。

「ステップイン」することなく、「ステップ」だけでどこを通っているかを確認できたり、関数の戻り値を確認できると、デバッグしやすいです。

以下の例は、架空の言語です。

1行に関数を2つ以上書くと、2つめ以降の関数にステップインしにくい

デバッグしにくい例
func_b内にステップインするためには、1回目の「ステップイン」でfunc_aにステップインします。「ステップオーバー」でこの行に戻ります。2回目の「ステップイン」でfunc_bにステップインします。

func_a(); func_b();

デバッグしやすい例
func_bの行で止まり「ステップイン」すると、func_b内にステップインします。

func_a();
func_b();

if文の条件部分と本体を1行にすると、ifの本体を通ったのかわからない

デバッグしにくい例
ステップ実行すると、if文のtrue/falseに関係なく、次の行に進みます。funcを呼んだかどうかがわかりづらいです。

if (1 < a) { func(); }

デバッグしやすい例
ステップ実行すると、if文がtrueなら、func()の行で止まります。

if (1 < a) {
    func(x);
}

if文の条件式が複雑だと、デバッグしにくい

デバッグしにくい例

if (x <= func_a() && y <= func_b()) {
}

デバッグしやすい例

function is_xxxx(x, y) {
    a = func_a();
    b = func_b();
    f1 = x <= a;
    f2 = y <= b;
    f = f1 && f2;
    return f;
}

if (is_xxxx(x, y)) {
}

関数Aの引数で関数Bを呼ぶと、関数Bの戻り値を確認しにくい

デバッグしにくい例
func_bの戻り値を確認するには、func_aにステップインする必要があります。
また「1行に関数を2つ以上書くと、2つめ以降の関数にステップインしにくい」と同じ問題があります。

func_a(func_b());

デバッグしやすい例
func_a(b);の行で止まると、変数のbの値が表示されます。

b = func_b();
func_a(b);

return式で関数Aを呼ぶと、関数Aの戻り値を確認しにくい

デバッグしにくい例
funcの戻り値を確認できません。

return func();

デバッグしやすい例
return result;で止まると、変数resultの値が表示されます。

result = func();
return result;

右辺の式内で関数を呼ぶと、戻り値を確認しにくい

デバッグしにくい例
func_aやfunc_bにステップインしないと、戻り値を確認できません。

x = func_a() + func_b();

デバッグしやすい例
x = a + b;の行で止まると、変数aや変数bの値が表示されます。

a = func_a();
b = func_b();
x = a + b;

判断と処理を分けて読みやすくする

判断と処理を分けると、読みやすく、テストしやすく、デバッグしやすくなります。

例は javascriptで書いています。

1.初期バージョン

最初に書くバージョンはだいたいこんな感じです。
「もろもろの処理」は、複数行だったり、if文やfor文を含むことがあります。

function func2 (a, b) {
    if (a > 10) {
        if (a > 20) {
            if (a > 30){
                もろもろの処理_1
            } else {
                もろもろの処理_2
            }
        } else {
            もろもろの処理_3
        }
    } else {
        もろもろの処理_4
    }
}

2.もろもろの処理をそれぞれ別メソッドにします。

function func2 (a, b) {
    if (a > 10) {
        if (a > 20) {
            if (a > 30){
                func2_1();
            } else {
                func2_2();
            }
        } else {
            func2_3();
        }
    } else {
        func2_4();
    }
}

function func2_1() {
    もろもろの処理_1
}

function func2_2() {
    もろもろの処理_2
}

function func2_3() {
    もろもろの処理_3
}

function func2_4() {
    もろもろの処理_4
}

3.「判断」と「処理」を別メソッドにします。

function func2 (a, b) {
    var num = case_number(a, b);
    process(num);
}

function case_number(a, b) {
    var num = 0;
    if (a > 10) {
        if (a > 20) {
            if (a > 30){
                num = 1;
            } else {
                num = 2;
            }
        } else {
            num = 3;
        }
    } else {
        num = 4;
    }
    return num;
}

function process(num) {
    switch (num) {
        case 1:
            func2_1();
            break;
        case 2:
            func2_2();
            break;
        case 3:
            func2_3();
            break;
        case 4:
        default:
            func2_4();
            break;
    }
}

4.判断内のif文のネストをelse〜ifで小さくします。

function case_number(a, b) {
    var num = 0;

    if (a <= 10) {
        num = 4;
    } else if (a <= 20) {
        num = 3;
    } else if (a <= 30) {
        num = 2;
    } else {
        num = 1;
    }

    return num;
}

5.デシジョンテーブル風のコメントをつけておきます。

/*
| # | a     | action  |
| - | ----- | ------- |
| 4 | <= 10 | func2_1 |
| 3 | <= 20 | func2_2 |
| 2 | <= 30 | func2_3 |
| 1 | > 30  | func2_4 |
*/
function func2 (a, b) {
   ...
}

6. if文の条件式が長いときは、それぞれ別メソッドにします。

function case_number(a, b) {
    var num = 0;

    if (is_later_equal(a, 10)) {
        num = 4;
    } else if (is_later_equal(a, 20)) {
        num = 3;
    } else if (is_later_equal(a, 30)) {
        num = 2;
    } else {
        num = 1;
    }

    return num;
}

function is_later_equal(a, x) {
    var f = (a <= x);
    return f;
}

最後に、func2メソッドの処理をとりだして、別クラスにします。

cordovaで開発したiPhoneアプリをappiumでテスト(2/2)

cordovaで開発したiPhoneアプリをAppiumでテストしたので、まとめました。

cordovaで開発したiPhoneアプリをappiumでテスト(1/2)
1.目標
2.simulator用appをビルド
3.appium他のインストール
4.Appiumデスクトップのインストール
5.Appiumデクトップを起動、Inspectorウィンドウで操作の記録

cordovaで開発したiPhoneアプリをappiumでテスト(2/2)
6.nodeでテストケース作成(アプリ起動のみ)
7.テストケースの実行
8.テストケース作成(座標をタップ、スクリーンショット保存)

6.nodeでテストケース作成

githubにappium公式サンプルソースがあります。
https://github.com/appium/sample-code

sample-code/examples/node/helpers/*.js
sample-code/examples/node/ios-simple.js
sample-code/examples/node/package.json
をダウンロードして、ios-simple.jsを改造します。

/Users/taro/projects/hello/platforms/ios/appium-testcaseの下に
helpers/*.js
ios-simple.js
package.json
を保存しました。

必要なnodeモジュールをインストールします。

$ cd /Users/taro/projects/hello/platforms/ios/appium-testcase
$ npm install

beforeメソッドのdesired変数は、「4.Appiumデクトップを起動、Inspectorウィンドウで操作の記録」のdesired capbilitiesの各項目を参考に設定してください。

テストケースの内容は、アプリを起動して、1秒間表示して、終了するだけです。

ios-simple.jsを編集します。

"use strict";

require("./helpers/setup");

var wd = require("wd"),
    _ = require('underscore'),
    Q = require('q'),
    serverConfigs = require('./helpers/appium-servers');

describe("ios simple", function () {
  this.timeout(300000);
  var driver;
  var allPassed = true;

  before(function () {
    var serverConfig = process.env.npm_package_config_sauce ?
      serverConfigs.sauce : serverConfigs.local;
    driver = wd.promiseChainRemote(serverConfig);
    require("./helpers/logging").configure(driver);

    var desired = {
      "appium-version": "1.4",
      platformName: "iOS",
      deviceName: "iPhone 7",
      platformVersion: "11.0",
      automationName: "XCUITest",
      app: "/Users/taro/projects/hello/app/Applications/HelloWorld.app",
    }; 

    return driver.init(desired);
  });

  after(function () {
    return driver
      .quit()
      .finally(function () {
        if (process.env.npm_package_config_sauce) {
          return driver.sauceJobStatus(allPassed);
        }
      });
  });

  afterEach(function () {
    allPassed = allPassed && this.currentTest.state === 'passed';
  });

  it ("test_1", function () {
    return driver
      .sleep(1000)
  });

});

7.テストケースの実行

appiumサーバの起動

Appiumデスクトップで[Start Server]しておくか、または、ターミナルで

appiumサーバの起動
$ appium &

appiumサーバの停止
$ pkill -f appium

テストケースの実行

$ cd /Users/taro/projects/hello/platforms/ios/appium-testcase
$ npm run ios-simple

iPhone simulatorの終了

$ pkill -f CoreSimulator

8.テストケース作成(座標をタップ、スクリーンショット保存)

Inspectorウィンドウで、xy座標をメモしてはクリックを繰り返して、テストケースを作りました。
次のように、座標指定のタップ、スクリーンショット保存処理、AlertダイアログのOKを追加しました。

"use strict";

require("./helpers/setup");

var wd = require("wd"),
    _ = require('underscore'),
    Q = require('q'),
    serverConfigs = require('./helpers/appium-servers'),
    fs = require('fs');

describe("ios simple", function () {
  this.timeout(300000);
  var driver;
  var allPassed = true;

  before(function () {
    var serverConfig = process.env.npm_package_config_sauce ?
      serverConfigs.sauce : serverConfigs.local;
    driver = wd.promiseChainRemote(serverConfig);
    //require("./helpers/logging").configure(driver);

    var desired = {
      "appium-version": "1.4",
      platformName: "iOS",
      deviceName: "iPhone 7",
      platformVersion: "11.0",
      automationName: "XCUITest",
      app: "/Users/taro/projects/hello/app/Applications/HelloWorld.app",
    }; 

    driver.saveScreenshot = function (path) {
      return driver.takeScreenshot().then(function(data) {
        fs.writeFile(path, data, "base64", function(err) {
          if (err) {
           throw err;
          }
        });
      });
    };

    return driver.init(desired);
  });

  after(function () {
    return driver
      .quit()
      .finally(function () {
        if (process.env.npm_package_config_sauce) {
          return driver.sauceJobStatus(allPassed);
        }
      });
  });

  afterEach(function () {
    allPassed = allPassed && this.currentTest.state === 'passed';
  });

  var tap_at = function (x, y) {
    var action = new wd.TouchAction();
    return action
      .press({"x": x, "y": y})
      .wait(100)
      .release();
  }

  it ("test_1", function () {
    return driver
      .sleep(1000)
      .saveScreenshot("/Users/taro/projects/hello/platforms/ios/appium-testcase/screenshots/01.png")

      .performTouchAction(tap_at(161, 464))
      .sleep(1000)
      .saveScreenshot("/Users/taro/projects/hello/platforms/ios/appium-testcase/screenshots/02.png")

      .acceptAlert()
      .sleep(1000)
      .saveScreenshot("/Users/taro/projects/hello/platforms/ios/appium-testcase/screenshots/03.png")
  });

});

最終的に、desired変数のdeviceName、platformVersion、appやスクリーンショット保存パスは、環境変数で渡すようにしました。
また、シミュレータでの実行が思ったより遅かったので、sleepで調整しています。

cordovaで開発したiPhoneアプリをappiumでテスト(1/2)

cordovaで開発したiPhoneアプリをAppiumでテストしたので、まとめました。

cordovaで開発したiPhoneアプリをappiumでテスト(1/2)
1.目標
2.simulator用appをビルド
3.appium他のインストール
4.Appiumデスクトップのインストール
5.Appiumデクトップを起動、Inspectorウィンドウで操作の記録

cordovaで開発したiPhoneアプリをappiumでテスト(2/2)
6.nodeでテストケース作成(アプリ起動のみ)
7.テストケースの実行
8.テストケース作成(座標をタップ、スクリーンショット保存)

当初、XcodeのXCUITestでwebviewのDOMを取得できなかったので、appiumを使ってみました。結局、appiumでもwebviewのDOMを取得できず、xy座標を指定してタップ操作を記述することにしました。それなら、XCUITestでテストケースを書いたほうがよかったかもしれません。

1.目標

全画面を遷移し、スクリーンショットを保存する。

対象機種のシミュレータ:
iPhone X、iPhone 8、iPhone 7 (11.0)、iPhone 7 Plus (11.0)、iPhone 6 (10.3)

2.simulator用appをビルド

cordovaプロジェクトの位置=/Users/taro/projects/hello
xcodeワークスペースの位置=/Users/taro/projects/hello/platforms/ios/HelloWorld.xcworkspace
appのファイル位置=/Users/taro/projects/hello/app/Applications/HelloWorld.app

ターミナルで次のsim_build.shを実行します。
app/Applications/HelloWorld.appが作成されます。

$ cd /Users/taro/projects/hello
$ ./sim_build.sh

/Users/taro/projects/hello/sim_build.sh

#!/bin/bash -x

WORKSPACE=HelloWorld
SCHEME=HelloWorld
CONFIG=Debug
SDK=iphonesimulator

xcodebuild \
  -workspace $WORKSPACE \
  -scheme $SCHEME \
  -configuration $CONFIG \
  clean \
  DSTROOT=${PWD}/app

xcodebuild \
  -workspace $WORKSPACE \
  -scheme $SCHEME \
  -configuration $CONFIG \
  -sdk iphonesimulator \
  install \
  DSTROOT=${PWD}/app

3.appium他のインストール

必要なものをインストールしてください。
ターミナルの cd する場所はどこでもかまいません。

Homebrewのインストール
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

rbenvのインストール
$ brew install rbenv ruby-build readline

RubyのパスをBashに追記
$ echo 'if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi' >> ~/.bash_profile
$ source ~/.bash_profile

Rubyのインストール
$ rbenv install --list
$ rbenv install 2.4.2
$ rbenv global 2.4.2
$ ruby -v

$ npm install -g appium
$ npm install -g appium-doctor
$ brew install carthage

環境確認
$ appium-doctor --ios

4.Appiumデスクトップのインストール

デスクトップ版 appium
https://github.com/appium/appium-desktop/releases

最新バージョンの appium-desktop-x.x.x.dmg をダウンロード、インストールしてください。

4.Appiumデクトップを起動、Inspectorウィンドウで操作の記録

Finder>アプリケーション>Appiumを起動してください。
[Simple]のまま、[start server]をクリックしてください。

黒いログコンソールが表示されます。
右上の虫メガネ[Start Inspector Session]ボタンをクリックしてください。

Inspectorウィンドウが表示されます。
Desired Capabilitiesタブで、次の5項目を設定してください。

項目
platformName text iOS
automationName text XCUITest
deviceName text iPhone 7
platformVersion text 11.0
app text /Users/taro/projects/hello/app/Applications/HelloWorld.app

platformName
“iOS”固定です

automationName
“XCUITest”固定です

deviceName
“iPhone 7″、”iPhone 7 Plus”、”iPhone 6″、”iPhone 6 Plus”などを入力します。

platformVersion
“10.3”、”11.0″などを入力します。
Xcodeで”9.3″シミュレータもダウンロード済みでしたが、appiumから”9.3″は起動できず諦めました。

app
「1.simulator用appをビルド」で作成したappファイルの絶対パスを指定してください。

[Start Session]をクリックしてください。
しばらくすると、iPhoneシミュレータが表示されます。
iPhoneシミュレータでテスト対象アプリが起動します。
Inspectorウィンドウにスクリーンショットが表示されます。

スクリーンショット上でマウスを動かしてみてください。
識別可能な画面要素が黄色くなり、クリックすると、緑になります。
ウィンドウの中央のApp Source領域には、ツリーが表示されます。
右側のSelected Element領域には、クリックした画面要素のXCUIElementツリーのxpathが表示されます。

cordovaで開発したアプリなので、画面要素はWebView内です。残念ながらDOM IDで画面要素を指定できないようです。画面要素が存在していること、属性が期待した値になっていること、などをアサーションしたいのですが、今回はあきらめました。

いろいろ試して、次の操作でテストケースを書くことにしました。

sleep(ミリ秒)
x, y座標指定のタップ
alertダイアログのOK
スクリーンショットの保存

iPhone 7でxy座標を調べて、iPhone 7 Plusなら座標を1.1倍することにし、iPhone Xは別に座標定義を用意することにしました。

画面ごとにスクリーンショットを保存し、担当者が見て確認することにしました。

(つづく)

三項演算子はデバッグしにくい

三項演算子はデバッグしにくいので、デバッグしやすさという観点では使わないほうがいいと思います。

三項演算子の例

x = (a < b) ? a : b;

if文の例

if (a < b) {
    x = a;
} else {
    x = b;
}

理由1:
デバッガでステップ実行したとき、if文のほうが処理の流れを追いやすいから。

三項演算子の文をデバッガでステップ実行すると、単に次の行に移動します。行を追っているだけでは、aとbのどちらを採用したのかがわかりません。a, b, xの値を読んだり、式を評価する必要があります。

if文をステップ実行すると、if の次に、x = a; または x = b; の行に移動します。どの選択肢に移動したのか、ひと目でわかります。

理由2:
選択肢が3つ以上になったとき、if文で書き直すから。

今は選択肢が2つですが、近い将来3つに増えるかもしれません。三項演算子で書いてあれば、if〜else if文で書き直すでしょう。それなら、今、if文で書いたほうがいいと思います。

理由3:
三項演算子を入れ子にした難解なコードを見たことがあるから。

見た瞬間、ここ触りたくねーと思いました。

この記事を書いた後、自分のソースを検索したら、予想より多く見つかりました。まあそんなもんですね。

この記事のタグは「コーディングスタイル」より「デバッガブル」だなと思い、「デバッガブル」で検索したら、いい記事が見つかりました。
デバッグしやすい、解析しやすいコードを書こう

e-Taxソフトが新しいソフトウェアのインストールを構成中です。

e-TaxソフトをWindows 7 Home Premium 64bit(FMV AH700/5A)にインストールしたところ、プログレスバーは100%まで進んだが、「e-Taxソフトが新しいソフトウェアのインストールを構成中です。」と表示したまま5分待っても終わらない。

CPU利用率は60%から25%へ下がり、HDDアクセスランプも付いていないので、インストール処理は終わっているかもしれないと思い、[キャンセル]ボタンをクリックしたが、反応なし。タスクマネージャからeTaxソフトインストーラを終了した。

スタート>すべてのプログラムに「eTaxソフト」フォルダが作成されていたが、コントロールパネル>プログラムのアンインストールの一覧に「e-Taxソフト」が見当たらない。

スタート>すべてのプログラム>eTaxソフト>eTaxソフトのアンインストールをしようとするが、「初期インストールには使えません」と表示されてしまう。

ファイルコピーはしたが、レジストリにインストール情報の登録するところでつまずいているようだ。

再度インストーラを実行すると「別のインスタンスが存在します」と表示されてしまうので、Windows再起動。

いろいろ試してみた。

インストーラexeで右クリック>管理者として実行…
結果:NG

インストーラexeで右クリック>プロパティ>互換性タブ>Windows Vista SP2
(参考 http://naked30s.com/how-to-install-e-tax-software-successfully/)
結果:NG

ノートPCにつないでいる外部モニタを外した。
結果:NG

セキュリティソフトを無効にした。
結果:NG

再起動してF8、セーフモードとネットワークで起動、インストーラexeを実行
結果:OK
途中「レジストリに登録できませんでした ??data.dll」と表示されたが、いつのまにかインストール完了まで進んだ。

リーダブルコードcakePHP版?find()の引数並びにarray()を記述しない

cakePHPの公式サイトには次のようなサンプルコードがある。引数並びにarray()を記述している。

$allPublishedAuthors = $this->Article->find('list', array(
	'fields' => array('User.id', 'User.name'),
	'conditions' => array('Article.status !=' => 'pending'),
	'recursive' => 0
));

この書き方のメリットは、下記の書き方と比較するとわかりやすい。array()を$paramsなどの変数に代入していないので前後の変数との関連を考えなくてもいいこと(下記 A,C)、この1まとまりの処理の途中に無関係なコードを記述できないこと(下記B)だと思う。

//A. これ以前に$paramsに代入しているだろうか?
$params = array(
	'fields' => array('User.id', 'User.name'),
	'conditions' => array('Article.status !=' => 'pending'),
	'recursive' => 0
);
//B. ここに無関係なコードを記述できてしまう。
$allPublishedAuthors = $this->Article->User->find('all', $params);
//C. これ以降に$paramsを参照しているところがあるだろうか?

しかし実務では次のデメリットのほうが大きいと思う。

1つ目は、引数並びが長すぎて読む気力が萎えてしまうこと。find()の閉じ括弧までが長すぎて、頭の中のスタックのプッシュ量が多い感じがする。

2つ目はデバッグしにくいこと。printデバッグしたくても、引数並びのarray()のままではvar_dump()できない。eclipse+xDebugでトレースする場合も、引数並びのarray()を表示することはできない。ソースファイルがあれば関数へステップインすると表示できるが、組み込み関数の場合はステップインもできない。

次のようにしたほうが読みやすくデバッグもしやすいと思う。

$params = array(
	'fields' => array('User.id', 'User.name'),
	'conditions' => array('Article.status !=' => 'pending'),
	'recursive' => 0
);
$allPublishedAuthors = $this->Article->find('list', $params);

さらに、array要素を1行1要素にすると、gitで直前のリビジョンとdiffしたとき変更箇所がわかりやすい。

$params = array(
	'fields' => array(
		'User.id',
		'User.name',
 	),
 	'conditions' => array(
 		'Article.status !=' => 'pending',
 	),
 	'recursive' => 0,
);
$allPublishedAuthors = $this->Article->find('list', $params);

アクション内で$this->XXX->find()を何回も呼んでいて行数が多いと感じたら、それぞれのfind()呼び出しをモデルのメソッドにするといいと思う。モデルのメソッドにすれば1行で呼び出すことができ、前後の変数との関連はないし、一連の処理の途中に無関係なコードの記述もできない。

$allPublishedAuthors = $this->Article->find_list_ArticleStatusIsPending();

なお、viewの$this->input()の2つ目の引数は、ロジックとは関係がないhtmlタグやcssなどが多く、引数並びにarray()を記述したほうが読みやすいと思う。

関連:リーダブルコード 8章 巨大な式を分割する

gitのブランチの名前の付け方

かつてSubversionを使っていたときは、ほとんどブランチを使ったことがない。慣例にしたがってtrunk、branches、tagsを用意するものの、trunkだけを使っていた。ブランチとタグの違いを理解していなかった。ブランチ操作を難しいものと思い込んでいたし、「変更履歴」と「以前の状態と比較できる」だけで満足していた。

gitを使うようになってからブランチ/マージを試してみたら、あっけないほど簡単だった。日常的にmasterブランチと開発ブランチを使うようになった。

するとブランチの名前の付け方を考えるようになった。最初はmasterとwork。次の段階では、チケット番号をつけてwork_1234 や ticket_1234で作業するようになった。この程度のざっくりとした運用で問題はないのだが、標準的なブランチ名の付け方や運用方法があるなら、知りたいと思っていた。

素晴らしい記事を発見した。ブランチは5個あるが、各ブランチの目的と運用方法が明確で迷うことはないと思う。

O-Showさんの日本語訳
http://keijinsonyaban.blogspot.jp/2010/10/successful-git-branching-model.html

Vincent Driessenさんの原文”A successful Git branching model
http://nvie.com/posts/a-successful-git-branching-model/

中央リポジトリ(例 github)

・master 現在の製品バージョン。
・develop 次回リリースの開発用。

開発者リポジトリ

・feature- 新規機能の開発用。developから分岐し、developへマージする。
・release-
 次回リリースの準備用。developから分岐し、developとmasterへマージする。
・hotfix-* 現在の製品バージョンのバグフィックス用。masterから分岐し、developとmasterへマージする。

※このブランチモデルをベースにしたgit-flow というプラグインもある。

gitブランチの名前の付け方2