稲枝の押入れ

いなえが適当なことを書いては、しまっておく場所

UnityのFixedUpdateとOnTrigerXXXとOnCollisionXXXの実行順序

調べたらすぐ出てくるんだけど自分用メモ。

Physics系は基本的に固定頻度でUpdateやらを回そうとするが、

  • FixedUpdate()
  • OnTriggerXXX()
  • OnCollisionXXX()

をどういう順番に実行するんだ?と思って手元でやってみたらどうもFixedUpdate()が一番最初っぽかった。

ググったら直ぐに公式ソースも見つかった。これ前にも調べて見たな、と思ったがまあポンコツなので忘れていた。

f:id:makiofinae:20190602232210p:plain
Physicsの呼び出し順序

結論から言うと上で出した順番のまんまで

  • FixedUpdate()
  • OnTriggerXXX()
  • OnCollisionXXX()

の順に呼ばれる。

以上。

Excelでセル内の文字列を取得しようとすると途中で途切れる

くっそくだらないが引っかかったのでメモ

タイトルの通り、C#Microsoft.Office.Interop.Excelを使ってセルの内容を取得していたら、一定の長さ以上の文字列について取り出しに失敗しているのに気づいた。

簡単なサンプルコードは以下。

とりあえず、1行目,1列目にaと10000文字入力したエクセルファイル、test.xlsxを用意してあるという前提だ。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CS_Test
{
    class Program
    {

        /// <summary>
        /// ガベージコレクションを実行
        /// </summary>
        static void ExecGC()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
        }

        /// <summary>
        /// COMオブジェクトの解放
        /// </summary>
        /// <param name="obj">開放したいCOMオブジェクト</param>
        static void ReleaseCOMObject(object obj)
        {
            // EXCELのCOMオブジェクトを開放する
            if (obj != null)
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
        }

        /// <summary>
        /// エクセルアプリケーションの解放
        /// </summary>
        /// <param name="app">excelアプリケーション</param>
        static void ReleaseExcel(Microsoft.Office.Interop.Excel.Application app)
        {
            // EXCELのCOMオブジェクトを開放する
            if (app != null)
            {
                app.Quit();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
                app = null;
            }
        }

        /// <summary>
        /// エントリポイント
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Microsoft.Office.Interop.Excel.Application excel = null;
            Microsoft.Office.Interop.Excel.Workbooks books = null;
            Microsoft.Office.Interop.Excel.Workbook book = null;
            Microsoft.Office.Interop.Excel.Sheets sheets = null;
            Microsoft.Office.Interop.Excel.Worksheet sheet = null;
            try
            {
                excel = new Microsoft.Office.Interop.Excel.Application();
                books = excel.Workbooks;
                book = books.Open(System.IO.Path.GetFullPath("test.xlsx"));
                sheets = book.Worksheets;
                sheet = sheets[1];

                //1行目、1列目を取得
                string cell1 = (sheet.Cells[1, 1]).Text;
                System.Console.WriteLine($".Textで抜き出したテキストのサイズ {cell1.Length}");
                string cell2 = (sheet.Cells[1, 1]).Value;
                System.Console.WriteLine($".Valueで抜き出したテキストのサイズ {cell2.Length}");

                System.Console.ReadKey();
            }
            finally
            {
                ReleaseCOMObject(sheet);
                ReleaseCOMObject(sheets);
                ReleaseCOMObject(book);
                ReleaseCOMObject(books);
                //一旦解放
                ExecGC();
                // EXCELのCOMオブジェクトを開放する
                ReleaseExcel(excel);
                //再度解放
                ExecGC();
            }
        }
    }
}

実行結果

.Textで抜き出したテキストのサイズ 8221
.Valueで抜き出したテキストのサイズ 10000

というわけで、 .Textで取り出すと8221文字以上は取り出せない

如何にもな名前だが、長い文字列を取り出したくても.Textを使ってはならない。.Valueを使おう。

ValueとTextの違いについてはExcelでセルの値を扱う(Value、Value2、Text、Formulaの違いのメモ)などをみるといい。

因みにMS公式のRange.Textに関するドキュメントにはこんなことどこにも書いていない。やりますねえ。

勿論僕はデータ作成者ではなく、Excelを処理したいと言われたらただ処理をするプログラムを書くだけだ。書くだけなのだが、そもそもとしていいたい。
1つのセルにこんなに大量の文字列を入れるのはやめましょう。

ポインタにconstをつけた時書き換え不能になる変数

超絶初歩的だが、constをつけた時のポインタの表す意味がたまにわからなくなるので自分用メモ。

int型へのポインタpは以下のように書ける

int * p;

この時*が型もしくは変数名についていることがあるが、それについては特に区別しない。

つまり、

[型名] * [変数名];

と書けるわけだが、このポインタ変数にconstをつけることを考えると、候補となる位置は

(1) [型名] (2) * (3) [変数名] (4);

が有り得そうだ。そして、実際に(1),(2),(3)の位置にはconstを置くことが出来る。

そして、このconstの位置によって、何にconstを付与しているかの意味が変わってくる。

具体的には、

  • ポインタ変数が保持している対象の変数のアドレス(=ポインタ変数の値そのもの)
  • ポインタ変数によってアドレスが保持されているオブジェクト(=ポインタ変数が指す先)

に対するconstの付与という2種類の付与の意味がある。ここでは前者を「指示変数」、後者を「被指示変数」と呼ぶことにする(一般的な呼び方ではなく、文章が長くなるのを避ける為の便宜的なもの)。

f:id:makiofinae:20190511115823p:plain
指示変数と被指示変数

実際に、上記(1),(2),(3)の3箇所について、constを置くことを考えると

//const1つ
const int       *       p;
      int const *       p;
      int       * const p;

//const2つ
const int const *       p;
const int       * const p;
      int const * const p;

//const3つ
const int const * const p;

の組み合わせが考えられるが、これらそれぞれについて表にすると、

宣言 指示変数の書き換え 被指示変数の書き換え
//const1つ
const int * p; ×
int const * p; ×
int * const p; ×
//const2つ
const int const * p; - -
const int * const p; × ×
int const * const p; × ×
//const3つ
const int const * const p; - -

となる(-になっているところはそもそも定義不能)。

簡単な確認コードは以下。

int main(){
    int hoge = 0;
    
    int * ip = &hoge;
    
    const int * cip = &hoge;
    int const * icp = &hoge;
    int * const ipc = &hoge;
    
    //const int const * cicp = &hoge;//error: duplicate 'const'
    const int * const cipc = &hoge;
    int const * const icpc = &hoge;
    
    //const int const * const cicpc = &hoge; //error: duplicate 'const'
    
    int fuga = 1;
    
    cip = &fuga;
    //*cip = 2; //error: assignment of read-only location '* cip'
    
    icp = &fuga;
    //*icp = 2; //error: assignment of read-only location '* icp'
    
    //ipc = &fuga; //error: assignment of read-only variable 'ipc'
    *ipc = 2;
    
    //cipc = &fuga; //error: assignment of read-only variable 'cipc'
    //*cipc = 2; //error: assignment of read-only location '*(const int*)cipc'
    
    //icpc = &fuga; //error: assignment of read-only variable 'icpc'
    //*icpc = 2; //error: assignment of read-only location '*(const int*)icpc'
}

ここまで見るとややこしいように見えるかもしれないが、簡単な覚え方があって、*より前のconstは被指示変数の書き換えを禁止し、*より後のconstは指示変数の書き換えを禁止すると覚えるといい。

f:id:makiofinae:20190511115922p:plain
constの位置と書き換え禁止対象

因みに上の確認コードのコメントにもあるように、同じ意味のconst付与が重複するとエラーになるので注意。

*より前のconstって指示変数と被指示変数、どっちの書き換えを禁止するんだっけ…となったら参照を思い出すといいかも。const付き参照を書く時は

const int ref& = hoge;

となるが、参照はどのオブジェクトを参照するかの書き換えはconstがついていなくても出来ない(=ポインタと同じように考えるなら指示変数は書き換えできないということ)。つまり、わざわざconstをつけるという事は、参照先の被指示変数の書き換えを禁止していることを意味している。 これをポインタの先程の覚え方と同じように「&より前にconstがある時は参照先の被指示変数を書き換えられなくする」と無理矢理に解釈すれば、「ポインタも*より前にconstがある時は被指示変数を書き換えられなくする」と思い出せる。

以上はオブジェクトへのポインタの意味の覚え方だが、もう少し汎用的にポインタを読めるようになりたいのであれば、ポインタ完全制覇に載っているので、こちらを読むことをおすすめする。

TortoiseHgからMercurialでブランチを作成しようとするとうまくいかない

日本語ドキュメントが少ないのでメモ

TortoiseHgでブランチを作成してpushしようとすると、うまくいかないことがある

普通は、ブランチを作成してpushしようとすると、

---------------------------
新規ブランチの作成
---------------------------
これからプッシュするチェンジセットは新しいブランチを作成します。連携先に新しいブランチを作成しますか?
---------------------------
Yes   No   
---------------------------

みたいなウィンドウが出てきて、Yesを押せば(下のコンソール部に警告は出るが)pushは無事行われてリモートリポジトリにブランチは作成される

ただし、既に同名ブランチが作成されている場合は新しくブランチを作ろうとすると

---------------------------
ブランチ変更確認
---------------------------
名前付きブランチ「{ブランチ名}」は既に存在します (最終リビジョンは 6)

---------------------------
ブランチを切り直し   現行のブランチへコミット   キャンセル   
---------------------------

みたいなウィンドウが出てくる。コレ自体はブランチを切り直しを選択すればローカルにブランチの作成は出来るのだが、デフォルトの状態だとpush出来ない。

pushしようとすると、コンソールには

中止: 新しいヘッド {ハッシュ値} が連携先のブランチ '{作成しようとしているブランチ名}' に作成されます!
ヒント: マージするか、新規ヘッドの反映に関して 'hg help push' を参照

的な警告が出ていて、上にもヒント: マージするか、新規ヘッドの反映に関して 'hg help push' を参照みたいポップアップ?が出てきたりする

恐らくこれはheadを増やすことは混乱の原因という風に考えているmercurialの思想に基づいていると思っているのだが、とにかくこのままだと何回やってもpush出来ない

どうすればいいかというと--forceオプションを追加してpushすればいい。しかしここまでツールでやっているのに一部だけコマンドラインを使うというのも「なら最初からコマンドラインでやれや」となるし、非プログラマが触りづらい

一応このオプションを付けてpushする方法もTortoiseHg上には用意されている。以下のようにする

f:id:makiofinae:20190331232643p:plain
TortoiseHg_toolbar

  • 上のツールボックス?から同期アイコン(上記画像の赤丸)を選択すると下半分が同期画面になる
  • 同期画面のオプションボタンを押す
  • pushやpullを強制(安全確認を無効化 --force)にチェックをいれSaveする
  • この状態でpushする

これで過去に作成したブランチと同名のブランチを新たに作成する内容のcommitであっても何も警告が出ないでpush出来る

ただし、ここにチェックを入れたままにしていると、push時の警告が出なくなるので必要のない時はチェックを外しておくことを推奨する

元のコミット画面に戻る時は上記画像の赤丸を選択するといい

TortoiseHgからpull/pushする際にパスを毎回入れなくてもいいようにする

日本語ドキュメントが少なすぎて「TortoiseHg パスワード 省略」とか「TortoiseHg パスワード 毎回」みたいな頭悪い検索をすると引っかからなくて忘れるたびに困るのでメモ

メニューバーの[ファイル]->[設定]から(リポジトリ名) リポジトリ設定タブを開き、左カラムからエクステンションを選んだら右でmercurial_keyringにチェックを入れる。

これで初回はパスを聞かれるものの次回以降はパス無しでpullやpushができる

mercurial_keyringチェックボックスがグレーアウトして選択できない時はTortoiseHgを再起動するといけたりする。

それでも無理な時はmercurial_keyringチェックボックスがあるところで右上のファイルを開くで設定ファイルを開いて

[extensions]
mercurial_keyring = 

といれれば大丈夫なはず

参考までに、mercurial_keyringを使うとセキュリティ的にもいいとか(普通にパスを保存すると設定ファイルに平文で置かれた)

詳しくは以下を参照 qiita.com

文字コードまとめ

はじめに

文字コード周りを勉強していて、とりあえず全体を軽く俯瞰したので、今後の学習のために一旦代表的な符号化文字集合と符号化方式等について挙げて簡単に説明をつけてみる。

自分用かつ走り書き(推敲なし)なのでフォーマット等乱れはあるかと思うのでご容赦いただきたい。

また、個人的に重要かと思ったところを拾ったので情報の過不足もあるかと思うがそちらもご容赦いただきたい

間違いもしくは抑えるべき重要な点についての漏れ等があった場合は指摘をいただけるとありがたい。

気が向いたらもう少しきれいにするかもしれない

ASCII

ISO/IEC 646

  • 符号化文字集合を定めるための規格
  • Information technology — ISO 7-bit coded character set for information interchange
  • ASCIIの変種
    • つまり、7bitの1byteコード
  • ASCIIをベースに、各国の都合に応じて文字を変更してもいい符号位置を定めている
  • ある符号に対して、各国で自由に文字を定められるところが10箇所ある。
  • ある符号に対して、2種類から文字を選べるところが2箇所ある

ISO/IEC 646 International Reference Version

JIS X 0201

  • 符号化文字集合
  • 「7ビット及び8ビットの情報交換用符号化文字集合
  • 日本版のISO/IEC 646
  • ASCIIのバックスラッシュ部分が円記号に、チルダがオーバーラインになっている
  • ラテン文字集合と片仮名集合を定めている
    • この片仮名集合が所謂「半角片仮名」を定めている
  • 8bitの1byteコード(この意味でISO/IEC 646の日本版、といっていいのかわからない。勿論ISO/IEC 646を満たしているのだろうけど)
  • 符号化方式
    • 7ビット符号
    • 8ビット符号

ISO/IEC 2022

  • 様々な文字コードに基礎を提供する役割
  • ISO/IEC 646では複数の言語を同時に扱うことが出来なかった為、それに対応するために策定
  • ASCIIを拡張するしくみ
  • 8ビットコードや2バイトコードが可能に
    • 2バイト文字集合の場合94*94=8836の符号位置がある
  • 8bit
  • CL,GL,CR,GRの概念の導入
  • 0x00 ~ 0x1F : CL
  • 0x20 ~ 0x7F : CR
  • 0x80 ~ 0x9F : GL
  • 0xA0 ~ 0xFF : GR

JIS X 0208

83JIS(1983年改定)

  • 非漢字の追加
  • 漢字の字体変更(簡略化)
  • 入れ替え
  • 漢字の追加

90JIS(1990年改正)

  • 漢字の追加(2文字)
  • 微妙な字体差

97JIS(1997年改正)

  • 規格の明確化
    • 包摂基準の明示
    • 漢字の典拠の調査(幽霊漢字対策)
  • 符号化方式

ISO/IEC 8859

  • 複数の符号化文字集合を定義した規格
  • ISO/IEC 2022に整合的な構造
  • 8bitの1byteコード
  • 合計15のパートから成る
    • Part 1: Latin alphabet No. 1
    • Part 2: Latin alphabet No. 2
    • Part 3: Latin alphabet No. 3
    • Part 4: Latin alphabet No. 4
    • Part 5: Latin/ Cyrillic alphabet
    • Part 6: Latin/ Arabic alphabet
    • Part 7: Latin/ Greek alphabet
    • Part 8: Latin/ Hebrew alphabet
    • Part 9: Latin alphabet No. 5
    • Part 10: Latin alphabet No. 6
    • Part 11: Latin/ Thai alphabet
    • Part 13: Latin alphabet No. 7
    • Part 14: Latin alphabet No. 8 (Celtic)
    • Part 15: Latin alphabet No. 9
    • Part 16: Latin alphabet No. 10  
  • GLはASCII、GRにはそれぞれのパートで各地域に応じた文字集合を割り当てる

ISO/IEC 8859-1(Latin-1)

  • 符号化文字集合
  • 「 Information technology — 8-bit single-byte coded graphic character sets — Part 1: Latin alphabet No. 1」
  • ISO/IEC 8859の1つのバージョン
    • つまり8bitの1byteコード
  • 西ヨーロッパ各国の言語を表すことが出来る
  • 現在も欧米を中心に使われている
  • NBSP,SHY等を含む

ISO/IEC 8859-2(Latin-2)

  • 「 Information technology — 8-bit single-byte coded graphic character sets — Part 2: Latin alphabet No. 2」
  • ISO/IEC 8859の1つのバージョン
    • つまり8bitの1byteコード
  • 中央ヨーロッパ・東ヨーロッパ各国の言語を表すことが出来る
  • Latin-1と共通する文字は同じ符号位置に配置されている

ISO/IEC 10646(UCS)およびUnicode

  • ISOは当初は4byteで1文字を表す固定方式を予定
  • 一方、業界団体がUnicodeという2byteで1文字を表す固定方式を策定しようとしていた
  • 同じ目的の異なる国際文字コードが並立するのは望ましくないため、統合作業が行われた
  • 4byteと言う建前は残しつつ、Unicodeに合わせて下位2byteにすべての文字を配置した
  • しかし、2byteには文字は入り切らなくなった
  • 互換性を保ちながら2byteから4byteに拡張する方法が考えられた
  • 結合文字の使用を可能にしてある
    • 1つの文字が複数の符号化表現を持ちうるため、正規化も用意
  • 統合漢字のもとになったいずれかの規格で区別されている文字の違いは統合漢字でも区別する(原規格分離規則 source separation rule)
    • 互換漢字

UCS-4

  • 符号化文字集合
  • 4byteコード
  • 各バイトが群・面・区・点に対応
  • 231の符号位置がある
    • 文字の符号化のためのコード空間としては十分すぎるほど広い
    • ISO/IEC 10646の2011年版以降、群00の面00から17面分以外(UTF-16で表すことが出来ない面)は削除された
  • 実質Unicodeの全ての

UCS-2

  • 符号化文字集合
  • 2byteコード
  • UCS-4の群00面00に当たる
    • とはいえ厳密にはbyte数が違うので符号も違う

BMP

  • 群00面00のことを基本多言語面(Basic Multilingual Plane = BMP)と呼ぶ
    • BMPはもともとのUnicodeにあたる
    • 使用機会の多い文字の殆どはここに含まれる

SMP

  • 群00面01のことを補助多言語面(Supplementary Multilingual Plane = SMP)と呼ぶ
    • 歴史的な文字
    • 専門分野の記号

SIP

  • 群00面02のことを補助漢字面(Supplementary Ideographic Plane = SIP)と呼ぶ
    • BMPに収まらなかった漢字

面0E

  • 普通の意味の文字ではない特殊用途のメタ文字の様なもの専用の面

JIS X 0221

JIS X 0212

JIS X 0213

  • 符号化文字集合
  • 2byteコード
  • JIS X 0208の上位互換
    • JIS X 0208を包含しているとみなせる
    • よってJIS X 0208と併用する必要はなくこれ単体で足る
  • JIS X 0208の反省を生かして、現代日本で使われている文字を符号化することを目指した
  • 「7ビット及び8ビットの2バイト情報交換用符号化拡張漢字集合」
  • 多くの文字が収録された(11233文字)
    • 漢字第3・第4水準
    • ISO/ISC 8859の第1部と第2部の文字をすべて含む
    • ASCII互換のための文字(一部JIS X 0208にはなかった)
    • アイヌ語表記用片仮名
    • 漢字のへんやつくり
  • JIS X 0208の1983改正における字体変更の変更前の文字の追加
  • 初版はJIS2000などとも呼ばれる
  • 合計9種類の符号化方式

JIS2004(2004年改正)

  • 例示字形の変更生
  • 表外漢字UCS互換(10文字)の追加

EUC-JP

ISO-2022-JP

  • 7bitの符号化方式
  • ASCII,JIS X 0201ラテン文字,JIS X 0208を使用
  • RFC1468として仕様公開
  • 第8bitが1のコード範囲は全く使用しない
  • エスケープシーケンスによるGLの文字集合切り替えを使う
    • 状態を持つ符号化方式
    • 初期はASCII

Shift_JIS

UTF-16

UTF-32

  • 各符号位置を4バイト固定幅で表現する符号化方式
  • UCS-4と実質同一になる
  • UTF-32BE(ビッグエンディアン)とUTF-32LE(リトルエンディアン)がある
  • UTF-16と同様にBOMを使用可能
    • BOMはU+FEFFを使う
    • ただし、符号単位が4バイトなので注意

UTF-8

  • Unicode,ISO/IEC 10646で定義
    • RFC3629として閲覧可能
  • 8ビット単位の符号化方式
  • 1つの符号位置の表現に1~4バイトを使用
    • かつては最大6バイト
  • ASCII互換
  • 冗長な表現が可能なため、最も短い符号化が必要
  • 本来BOMは関係がないはずだが、BOM付きがある
    • UTF-8のデータであることの印として使われる
    • BOMはEF BB BF

CESU-8

  • UTF-16で表現可能なBMP外の符号位置を直接UTF-8で符号化しない方式
  • UTF016のサロゲートペアの上位下位それぞれの符号位置をUTF-8で符号化してつなげる
  • UTF-8であれば4バイトで符号化される部分が6バイトで符号化されたりする

Modified UTF-8

  • CESU-8に似た方式
  • Javaのクラスファイルで使われているらしい
  • U+0000を表すのにC080という2バイトを用いる

Githubのプランについて

GithubがPrivateリポジトリを無料プランで使えるようにしたと発表した事について騒ぎになっていたが、そもそもプランが色々変更されているみたいなので、それぞれがどんな感じなのか自分向けの備忘録として残しておく

プランの概要

個人向け

  • Free プラン
  • Pro プラン
    • 7ドル/月
    • 旧Developerプラン
    • Freeプランと同等の機能はもちろん使える
    • privateリポジトリに参加できる共同作業者に制限がなくなる
    • 追加でツールや解析機能?等を使える
    • privateリポジトリでも以下が使える

団体向け

  • Team プラン
    • 9ドル/一人あたり月
      • 最低5人分から契約可能
      • 最初の5人分は1人あたり5ドル/月
      • 5人を超えたところから上記の額分足されていく
      • 例えば7人チームなら5*5 + 9*2 = 43ドルが毎月かかる
    • OSSのチームなら無料
    • 大体Proプランでできることはできるっぽい
    • 集団開発のための機能(マネジメントとか)がつく
  • Enterprise プラン
    • 21ドル/一人当たり月
    • 自鯖Githubを立てるという選択ができるようになる
    • 優先したサポートが受けられるとか

参考

全てのプラン

https://github.com/pricing

料金設定について詳細

https://help.github.com/articles/github-s-billing-plans/

今回のリリースについて

https://blog.github.com/2019-01-07-new-year-new-github/

個人プランについて

ここ読めば日本語で概要はわかる
GitHubが無料でプライベートリポジトリを無制限に作れるようになったぞ☆