BlankTar

about | blog | works | photo

何を思ったのか、Elixirなる言語を触り始めました。
なんだかよく分かりませんが、なんだかとっても楽しい言語です。
ただ、新しい言語だけあってやたらとドキュメントが無いのがかなしい。

で、この記事はElixirを使ったディレクトリの操作についてのまとめです。

p.s. 2016-06-19

ファイルの読み書きについての記事も書きました。併せてどうぞ。

ファイルの存在確認

あるファイルが存在するかどうか確認するにはFile.exists?関数を使います。

iex> File.exists? "/"
true

ディレクトリかどうか調べる

ファイルなのかディレクトリなのかを見分けるにはFile.dir?関数を使います。

iex> File.dir? "/dev"
true
iex> File.dir? "/dev/null"
false

ディレクトリの中身を見る

File.ls関数でファイル/ディレクトリの一覧を取得出来ます。

iex> File.ls
{:ok, ["files", "of", "current", "directory"]}
iex> File.ls "/path/to/directory"
{:ok, ["hoge.txt", "fuga.mp3", "foo.png"]}

引数省略でカレントディレクトリの情報を取得出来るとか、まんまシェルのlsコマンドって感じ。

カレントディレクトリを変える

ls関数があればcd関数もあります。

iex> File.cd "/path/to/dir"
:ok

lsでは引数省略が出来ますが、こっちは引数省略は出来ないようです。

cwd関数でカレントディレクトリを取得出来ます。

iex> File.cwd
{:ok, "/mnt"}

ディレクトリを作ったり消したり

ディレクトリの作成はmkdir関数で。
mkdir_p関数を使うと親ディレクトリも込みで作ってくれます。

iex> File.ls
{:ok, []}
iex> File.mkdir "dir"
:ok
iex> File.mkdir_p "path/to/dir"
:ok
File.ls
{:ok, ["dir", "path"]}

普通にシェルって感じです。

ディレクトリの削除にはrmdir関数を使います。
rmdir関数は空のディレクトリしか消せませんが、rm_rf関数を使えば中身があっても消せます。もう完全にシェルって感じです。

iex> File.mkdir_p "hoge/fuga/foo"
:ok
iex> File.rmdir "hoge/fuga"
{:error, :eexist}
iex> File.rm_rf "hoge/fuga"
{:ok, ["hoge/fuga", "hoge/fuga/foo"]}
iex> File.rmdir "hoge"
:ok

エラーチェックを省略する

ここまでの例では、戻り値の最初の値は全て:okや:errorになっていました。
Elixirではこの値を使ってエラーチェックをするのが通常らしいです。

エラーチェックが面倒臭かったら、関数名の後に感嘆符を付けると良いようです。
感嘆符を付けた関数を使うと、戻り値で失敗を伝える代わりに例外を投げてくれるようになります。

こんな感じ。

iex> File.ls "not-found-directory"
{:error, :enoent}
iex> File.ls! "not-found-directory"
** (File.Error) could not list directory not-found-directory: no such file or directory
	(elixir) lib/file.ex:1167: File.ls!/1

ls以外の関数でもFileモジュールの中の関数ではだいたい使えるっぽいです。

参考: File - Elixir v1.2.5

dockerというコンテナ型の仮想化ソフトがありますよね。
セキュリティが宜しくないとかで、置き換えを目指すrktという別のソフトウェアが出て来ていたりします。

調べてみたところ、dockerグループに属した一般ユーザーがrootの権限を使えるらしいです。ヤバそうです。試してみました。

ひとまず、ubuntuか何かのイメージを落してきます。使うイメージはなんでも良いと思います。
ちなみにホストマシンにはCoreOSを使ってみました。

ホストマシン $ docker pull ubuntu

出来たら、起動します。

ホストマシン $ docker run -itv /:/mnt ubuntu /bin/bash

ホストマシンのルートディレクトリを/mntにマウントしている、というのがポイントです。
あとのオプションは適当に調べてください。

次に、ホストマシンのルートディレクトリにchrootを行ないます。

コンテナ # chroot /mnt /bin/bash

これでホストマシンのrootに(擬似的に)なれました。

rootのパスワードを変えます。

chrootしたあと # passwd

これが出来たら、あとはexit2回でマシンを閉じます。

設定したパスワードでログイン出来るか試してみましょう。

ホストマシン $ su -
Password:

普通にrootになれると思います。

ね、簡単でしょう?
共有サーバーで運用する場合、dockerグループも迂闊に渡さないようにしたほうが良さそうです…。

openFrameworks/ofxCvで笑い男を作った記事の続きです。
先程の記事では回りのリングが固定だったのですが、ちゃんと回るようにしてみます。

openFrameworksで描画するものを回転させるときにはofRotateというやつを使うようです。
ただ、このofRotateというやつを呼んでしまうと座標系が不思議なことになるので、他のものを描画するときに影響が出てしまいます。
そうなると困るので、ofPushMatrixofPopMatrixという二つの関数を使うことで影響を閉じ込めるようにして使用します。

文章だけだとややこしいので、ソースコードを。

#include <ofMain.h>
#include <ofxCv.h>


class ofApp : public ofBaseApp {
private:
	ofVideoGrabber cam;
	ofxCv::ObjectFinder finder;
	ofImage face, ring;
	int count;

public:
	void setup() override {
		cam.setup(640, 480);

		finder.setup("haarcascade_frontalface_default.xml");
		finder.setPreset(ofxCv::ObjectFinder::Fast);

		face.loadImage("face.png");
		ring.loadImage("ring.png");
	}

	void update() override {
		cam.update();

		if(cam.isFrameNew()){
			finder.update(cam);
		}
	}

	void draw() override {
		cam.draw(0, 0);

		for(int i=0; i<finder.size(); i++){
			ofRectangle rect = finder.getObjectSmoothed(i);

			{
				ofPushMatrix();

				ofTranslate(rect.getCenter());

				rect.width *= 1.5;
				rect.height *= 1.5;

				{
					ofPushMatrix();

					ofRotate(-count/2);
					ring.draw(-rect.width/2, -rect.height/2, rect.width, rect.height);

					ofPopMatrix();
				}

				face.draw(-rect.width/2, -rect.height/2, rect.width, rect.height);

				ofPopMatrix();
			}
		}

		count++;
	}
};


int main() {
	ofSetupOpenGL(640, 480, OF_WINDOW);

	ofRunApp(new ofApp());
}

コンパイルするときはOpenCVに同梱されているhaarcascade_frontalface_default.xmlと、笑い男の顔(face.png)、笑い男の後ろのリング(ring.png)の三つが必要です。
プロジェクトのディレクトリのbin/data以下に置いてください。

drawメソッドの中を見ていただくと、for文の中で妙なブロックを作っていることが目につくかと思います。
こいつは分かりやすいように書いただけで、プログラム的には何の意味もありません。
肝心なのはそのすぐ内側にあるofPushMatrixofPopMatrixです。この二つの関数で囲われた範囲で行なわれた座標系への操作(このプログラムではofTranslateofRotate)は外部に影響しません。
イメージ的には、ブロックの中の処理がブロックの外に影響しないよ、って感じですね。

ofTranslateというのは原点の座標を設定するための関数です。
初期状態で(0, 0)の位置に何かを描画しようとすると左上に描画されますが、例えばofTranslate(320, 240)と呼んだあとに(0, 0)に描画しようとすると画面上の(320, 240)に描画されるようになります。
このプログラムでは、顔の中心を原点に設定するようにしています。
見栄えするように認識した矩形の1.5倍のサイズで描画させているのですが、ofTranslateを使用することでこういった処理がやりやすくなります。

肝心の画像を回転させる処理はofRotateで行なっています。原点を中心にして回転するので、ここでもofTranslateの設定が効いています。
設定する値はDegreesらしいです。ラジアンじゃない普通の角度ですね。

そんな感じで、わりと簡単に画像を回すことが出来ました。
超簡単とはいかないけれど、この方法なら画像でなくても何だって歪ませたり回したり出来て楽しそうな感じですね。
だいぶ見辛くなるので、ブロックで囲うとかそういう工夫をした方が良いかもしれませんが…。

参考:
openFrameworks 入門編(2) - こじ研(openFrameworks)
ofMesh | openFrameworks

[ << ] [ 3 ] [ 5 ] [ 7 ] [ >> ]