Author Archives: admin

JavaScriptの難しいところ覚書

C++プログラマやJavaプログラマにとってJavaScriptの分かりづらいところを解説。

スコープ

C++では{}で括ったブロックがスコープになるがJavaScriptではスコープにならない。

2つのaは同じaになる。

関数はスコープを持つ

上のコードでfunction内のvarを外すと同じaを参照する。

コンパイルと実行

JavaScriptの実行は2段階で行われる。最初は変数を割り当て、次に実行する。割当時にはどのスコープにどの変数があるかを確定する。varによる変数の宣言や変数への書き込みは割当であり、変数の読み込みは割当処理ではスルーされる。

上記のコードではa,b,cは割当時に割り当てられるが、dは割り当てられないので実行時にエラーになる。cは書き込み処理なので割当時に割り当てられる。cでもエラーにしたい場合はファイルの最初に"use strict"(ダブルクオーテーション含む)と記述する。

オブジェクトと辞書

オブジェクトと辞書は同じ。

Objectは実際は関数である(後述)。

関数とオブジェクト

JavaScriptにはクラスがない。クラスのようなものをつくりたいときは関数で行う。

newを使うと、空のオブジェクトをつくりそれを暗黙の引数として渡す。関数内ではthisとして参照しそのオブジェクトを返す。

this

C++と同じようにオブジェクトのメンバ関数をコールすると暗黙の引数thisが渡される。

getasetaではthisを参照しているので関数を呼び出したオブジェクトがthisになりその値が変わる。

getcsetcではthisを参照していないのでオブジェクトは変更されない。そもそもこのcはオブジェクトに含まれてはおらず関数funcが持っている変数である。getcsetcはそのcを参照するがstaticでもなく、newでオブジェクトがつくられるごとにつくられそれが参照されている。よってcはオブジェクトがもつprivate変数のように扱える。

ここでnewを使わずにfuncをコールするとthisWindowオブジェクトになる。このオブジェクトは実行環境で変わり、ブラウザ上ではWindowオブジェクトになる。グローバルに宣言された変数はこのWindowオブジェクトのプロパティになっている。

prototypeと__proto__

関数はprototypeメンバとしてObjectをもつ。この関数でnewしてつくられたオブジェクトは__proto__メンバをもち同じObjectをもつ。

オブジェクトのプロパティを参照するとき、そのプロパティが見つからなかった場合は、__proto__から探す。よって関数のprototypeにあるプロパティを持たしておくと、オブジェクトで共通のプロパティを持つことができる。

prototype自体もオブジェクトでObjectは関数なのでprototype__proto__をもつ。よってあるプロパティを参照してそれが見つからないとき__proto__から見つけようとするがそれもないときは__proto__.__proto__から見つけようとする。よってObject.prototypeにプロパティを設定しておくとすべてのオブジェクトで共通のプロパティを持つことができる。

Object.prototype__proto__nullになっているので無限ループにはならない。

Windows10でsvchost.exeのグループ化する

svchostとは

svchost.exeはサービスを提供する実行ファイル、サービスとはユーザがサインインしていなくてもバックグラウンドで動いているプロセス。Windows10のCreators Update (version 1703)からサービス1つにつき1プロセスで起動(分割サービス)するようにしたため多くのサービスがタスクマネージャなどに表示される。ただしこれは常に行われるわけではなくメモリのサイズが3.5Gより大きければ分割サービスになる。3.5G以下の場合は以前のWindowsのようにサービスがグループ化される。グループ化といってもすべてのサービスが1つのプロセスで実行されるわけではなくある程度は分けられる。

分割サービスによりいくつかの利点がある。

  • プロセスで分けられているため1つのサービスに不具合があってもだのサービスに影響しない。
  • 特権などはプロセスごとに持つため設定しやすくなる。
  • CPUの使用率を制限するときもプロセス単位なのでやりやすくなる

ただし、プロセスをたくさん起動するとメモリ効率は悪くなるので、ここでは分割サービスになっているシステムをグループ化に戻す方法を紹介する。

分割サービスの状態:多くのサービスがある

manysvchost
Taskmanager shows many svchost.exe processes

8Gでサービスをプロセスに分けるように設定

レジストリキー:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SvcHostSplitThresholdInKBの値を8Gで設定する。実際の値はキロバイトなので、8388608になる。( = 8 * 1024 * 1024 )

svchost-split-from-8g
The value of the highlighted item is set 8G, if the actual memory is above this value, services will be splitted.

再起動すると反映される。

サービスがグループ化される

svchosts are grouped

サービスがグループ化されてsvnchost.exeの数が減った。

プロセスが実行しているサービスを確認する

Process Explorerでできる。svchost.exeをダブルクリックしてから’Services’タブを表示すると以下のようにサービスの一覧が表示される。

参考リンク

Changes to Service Host grouping in Windows 10

[Windows 10 Fix] Why Too Many Svchost.exe (Service Host) Process Running in Task Manager

chrome ver 69で形の変わったタブを元に戻す

Google chromeがversion69になるとタブの形が変わって以下のようになる。

chrome69-newtab

元に戻す

オムニボックス(アドレスバー)に以下を入力。

chrome://flags/#top-chrome-md

以下のように、UI Layout for the browser’s top chromeをNormalに変える。変更後Chromeを再起動すると元に戻る。

一度だけ初期化する処理をstaticとラムダで行う(C++)

以下のソースはある機能が利用可能かの状態を返す。一度だけ初期化するのでstaticとラムダ関数で行っている。

最初に呼ばれたときはラムダ関数を実行し、次からはstatic変数の値を返す。

ラムダ式

ラムダ式の戻り値はreturnから自動で推論される。この場合はboolになる。

スレッド

C++11でstatic変数のスレッドセーフが保証されたので、上記ラムダ式が2度動くことはない。

ソースコード

https://github.com/ambiesoft/blogprogs/tree/master/5075/src

Qt CreatorでQtのソースコードにステップ・インする

Qtソースコードをインストールする

Install Qt source code
Install Qt source code

Qt Creatorでソースコードのパスを設定する

設定するパスは{QtInstallDir}\Qt\5.11.0\Srcになる。

Add Qt source code directory
Add Qt source code directory

Qt Creatorでデバッグしてステップ・インする

これでQtのソースコードにステップ・インすることができる。Qtのソースコードにブレークポイントを設定することもできる。

サンプルソースコード

ソースコード

正規表現の先読みと後読み

すごく難しい。

肯定先読み

以下のパターンを考える。

以下の文字列はマッチしない

参照:https://regex101.com/r/ii0Brz/1

アルゴリズム

  • 123まではヒットしないのでスルー
  • Aがヒット
  • Bがヒット
  • Bがヒットした時点で、検索開始位置はBになる、これがCとヒットしないのでマッチしない。

このパターンはPositive Lookaheadと呼ばれる。日本語だと肯定先読み。意味としてはPositiveならそのまま進めるくらいの意味だと思う。

Bがヒットした時点で(?=)はパターンから消えて、パターンACが文字列BC456から検索されるといってもいい。

肯定後読み

同様にパターンA(?<=B)CABC456にマッチしない。参照:https://regex101.com/r/tEyPG2/1

アルゴリズム

  • Aがヒット
  • Bがヒット
  • Bがヒットした時点で、パターンのA、文字列のCから検索されてマッチしない。

別の言い方でまとめ直し

パターン A(?=B) は、
Aの次にBが来るもののA

パターン A(?=B)C は、
Aの次にBが来るもののA、の次にCが来るもの
よって絶対マッチしない。

パターン (?<=B)C は、
Cの前にBが来るもののC

パターン A(?<=B)C は、
Aの次に、Cの前にBが来るもののC
よって絶対マッチしない。

C++メモリが確保できないときの処理 Windows

メモリが確保できないときのデフォルトの処理

malloc

NULLを返す

new

std::bad_alloc例外を投げる。

_set_new_handler

_set_new_handlerを使うと、newでメモリが確保できなかったとき呼ばれる関数(ハンドラ)を指定できる。この関数はガーベージコレクションとして使われることが想定されていて、0以外を戻すと再度メモリ確保が試みされて失敗すればまたハンドラが呼ばれる。0を返すと失敗で、std::bad_alloc例外が投げられる。

上記ソースでは試していないが、_set_new_mode(1)を呼べば、mallocのときでも同様の処理ができるようだ。

ソースコード

git rev-parse

gitのrev-parseコマンドは外部的な表現のコマンドを内部的な表現に変換する。例えばHEADなどをSHA1のハッシュ文字列に変換する。

git rev-parse –abbrev-ref=strict HEAD