カテゴリ:IT( 162 )
拡張子なしで open-junk-file したら、ディレクトリを作るようにする
Text::Xslate みたいなテンプレートシステムを試すときに、ファイルじゃなくてディレクトリが作れると便利。ということで、open-junk-file で拡張子がない (というか、ファイル名に "." が含まれない) 名前を指定すると、ディレクトリをつくるようにしてみた。

popwin.el との兼ね合いで、少し微妙なコードになっている。


(defun open-junk-file ()
"Open a new file whose filename is derived from current time.
You can write short program in it. It helps to try-and-error programs.

For example, in Emacs Lisp programming, use M-x `open-junk-file'
instead of *scratch* buffer. The junk code is SEARCHABLE."
(interactive)
(let* ((file (format-time-string open-junk-file-format (current-time)))
(dir (file-name-directory file)))
(make-directory dir t)
(let ((newfile (read-string "Junk Code (Enter extension): " file)))
(if (string-match "\\." newfile)
(funcall open-junk-file-find-file-function newfile)
(progn (make-directory newfile t)
(find-file newfile))))))


diff -u open-junk-file.el{.org,}

--- open-junk-file.el.org 2011-04-16 15:13:58.000000000 +0900
+++ open-junk-file.el 2011-04-16 15:34:50.000000000 +0900
@@ -137,7 +137,12 @@
(let* ((file (format-time-string open-junk-file-format (current-time)))
(dir (file-name-directory file)))
(make-directory dir t)
- (funcall open-junk-file-find-file-function (read-string "Junk Code (Enter extension): " file))))
+ (let ((newfile (read-string "Junk Code (Enter extension): " file)))
+ (if (string-match "\\." newfile)
+ (funcall open-junk-file-find-file-function newfile)
+ (progn (make-directory newfile t)
+ (find-file newfile))))))
+

;;;; Bug report
(defvar open-junk-file-maintainer-mail-address



参考:
使い捨てコード用のファイルを開く - (rubikitch loves (Emacs Ruby CUI Books))
[PR]
by fkmn | 2011-04-16 17:03 | IT
PHP の関数
PHP の関数について、書き散らしたメモ。

関数宣言
<?php
function foo() {
// 処理
}


引数のデフォルト
<?php
function say_hello($greeting, $name = 'World') {
echo "$greeting, $name!", PHP_EOL;
}

say_hello('Bye', 'fkmn'); //=> Bye, fkmn
say_hello('Hello'); //=> Hello, World

// 呼び出し時に、デフォルトの無い引数が指定されていない場合は、
// 警告が発生
say_hello(); //=> 警告


関数から値を返すときには、return で明示する必要あり
<?php
function bar() {
1;
}

echo bar(); //=> なにも返ってこない

function baz() {
return 1;
}

echo baz(), PHP_EOL; //=> 1


変数のスコープ
<?php
$var = 'This is a global variable';

function hoge() {
echo "var is '$var'.", PHP_EOL; // $var is undefined
$var = 'This is a local variable';
echo "var is '$var'.", PHP_EOL; // $var is defiend

// $GLOBALS 配列を通して、グローバル変数にアクセスする
echo "var is '$GLOBALS[var]'.", PHP_EOL;
//=> $global is defiend

$GLOBALS['var'] = 'Called by hoge';
}

function fuga() {
// もう一つのグローバル変数へのアクセス方法
global $var;
echo "var is '$var'.", PHP_EOL; // $var is undefined

$var = 'Called by fuga';
}

hoge();
fuga();

echo $var, PHP_EOL; //=> 'Called by fuga'

[PR]
by fkmn | 2010-04-15 22:43 | IT
PHP の配列
PHP の配列についての、覚え書きというか書き散らし。


いきなり要素に突っ込んで、配列を作成
<?php
$vegetables['corn'] = 'yellow';
$vegetables['beet'] = 'red';
$vegetables['carrot'] = 'orange';

echo $vegetables['corn'] . '<br />';
echo $vegetables['beet'] . '<br />';
echo $vegetables['carrot'] . '<br />';


array 関数を利用 (key あり)
<?php
$dinner = array(0 => 'Sweet Corn and Asparagus',
1 => 'Lemon Chicken',
2 => 'Braised Bamboo Fungus',
str => 'Bare String Key');

echo $dinner[0] . '<br />';
echo $dinner[1] . '<br />';
echo $dinner[2] . '<br />';
echo $dinner['str'] . '<br />';


array 関数を利用 (key なし)
<?php
$dinners = array('Sweet Corn and Asparagus',
'Lemon Chicken',
'Braised Bamboo Fungus',);

echo $dinners[0] . '<br />';
echo $dinners[1] . '<br />';
echo $dinners[2] . '<br />';


key を指定せずに代入すると、配列の最後に追加される
<?php
$dinners[] = 'Added value';
$dinners[] = array('a', 'b', 'c');

echo $dinners[0] . '<br />';
echo $dinners[3] . '<br />';
echo $dinners[4] . '<br />'; //=> Array
echo $dinners[4][0] . '<br />'; //=> a


count() で配列の要素数を求める。未定義の変数に対する count() は 0 が返る。
<?php
echo count($dinners) . '<br />'; //=> 5
echo count($undefined_value) . '<br />'; //=> 0


空配列の作成
<?php
$empty_array = array();
echo count($empty_array) . '<br />'; // => 0


配列の繰り返し
<?php
echo '<table>';
echo '<tr><th>$key</th><th>$val</th></tr>';
foreach ($dinners as $key => $val) {
echo "<tr><td>$key</td><td>$val</td></tr>\n";
}
echo '</table>';


foreach 内で $key や $val を変えても、元の配列には影響しない。
元の配列を変える場合には $key をインデックスとして使う。
<?php
foreach ($dinners as $key => $val) {
if ($key % 2) {
$key = 'not influenced';
$val = 'not influenced';
}
else {
$dinners[$key] .= ' (modified in foreach)';
}
}

echo '<table>';
echo '<tr><th>$key</th><th>$val</th></tr>';
foreach ($dinners as $key => $val) {
echo "<tr><td>$key</td><td>$val</td></tr>\n";
}
echo '</table>';



foreach は、配列に追加された順番で要素にアクセスする。インデックス順でアクセスしたい場合は、for を使う。
<?php
$letters[0] = 'A';
$letters[1] = 'B';
$letters[3] = 'D';
$letters[2] = 'C';

foreach ($letters as $letter) {
echo $letter;
}
//=> ABDC

echo '<br />';
for ($i = 0, $len = count($letters); $i < $len; $i++) {
echo $letters[$i];
}
echo '<br />';
//=> ABCD


array_key_exists => キーの存在チェック。
<?php
if (array_key_exists(1, $letters))
echo 'key "1" exists in $letters. <br />';

if (array_key_exists(10, $letters))
echo 'key "10" exists in $letters. <br />';


in_array => 値の存在チェック。
<?php
if (in_array('A', $letters))
echo 'value "A" exists in $letters. <br />';

if (in_array('Z', $letters))
echo 'value "Z" exists in $letters. <br />';


2a問題に注意。in_array の判定に型を含める場合は、3番目の引数に TRUE を渡す。
<?php
$falses[] = false;
if (in_array('', $falses)) {
// ここを通る!!
echo 'value (EMPTY_STRING) exists in $falses. <br />';
}

if (in_array('', $falses, TRUE)) {
// ここは通らない
echo 'value (EMPTY_STRING) exists in $falses. <br />';
}


implode, 配列要素を文字列で連結
join , implode のエイリアス
unset , 配列から要素を削除する
<?php
echo implode(', ', $letters) . '<br />';
unset($letters[0]);
echo join(', ', $letters) . '<br />';


explode, 文字列をデリミタで分割
split , explode のエイリアス
<?php
$alphabet = 'A,B,C,D,E,F,G';
$alphabets = explode(',', $alphabet);
echo 'The second element of $alphabets is ' . $alphabets[1] . '<br />';

// デリミタに空文字列を指定すると、explode は FALSE を返す
$alphabets = explode('', $alphabet); //=> FALSE


文字列を文字に分解する場合は、pgrep_split (デリミタに正規表現を指定できる) を使う
参考: PHP: preg_split - Manual
<?php
$str = 'string';
$chars = preg_split('//', $str, -1, PREG_SPLIT_NO_EMPTY);
print_r($chars);

[PR]
by fkmn | 2010-04-12 23:55 | IT
PHP の文字列比較
一昔前に、PHP の文字列比較が話題になってたなぁ、という事を思い出したので、ググってまとめておく (「2a 問題」という名前がついているらしい)。


簡単に書くと、
if ('2a' == 2) {
 // ここ通る
}
って事らしい (・・・ゴクリ)。

とりあえずは、文字列の比較には === を使っておくのが無難そう。
ってか、この仕様、ユニットテスト書くときに問題になりそうなんだけど、どうなんだろう・・・?
[PR]
by fkmn | 2010-04-10 22:45 | IT
PHP 始めてみた
今後の仕事で必要になりそうなので、「初めてのPHP5」を片手に、PHP を始めてみた。

というわけで、お約束のHello, World!!
<!DOCTYPE html>
<html>
<head><title>PHP says hello</title></head>
<body>
<b>
<?php
print "Hello, World!!";
?>
</b>
</body>
</html>
実行結果

お手軽度はかなり高い印象。ただ、キーワードと関数名が case insensitive っていうのはマジデスカ?
ちょっと不安だぜ、PHP。
[PR]
by fkmn | 2010-04-08 22:59 | IT
Remedie 入れてみた
Mint's log: Remedieをインストール」で紹介されている手順ほぼそのままで、あっさりインストールできた (git はインストール済みだったので、そこは飛ばしたけど)。違った点というと、t/plagger/plugins/Discovery-Sites/base.t が fail しなかったぐらいか。

a0057891_0242928.jpg

 でも、いまのところ、追っかけたい動画サイトとかって、特に無いんだよね。何かおすすめがあれば、教えてください。

# 追記
 とりあえず、「NHKオンライン」と「YAPC::TV (エラー (#2048) が出て、動画が再生できなかった) 」を登録してみた。
[PR]
by fkmn | 2009-04-16 23:55 | IT
「C# エッセンシャルズ」まとめ その4

2.13 デリゲート (p.70, 71)

 メソッドを関数オブジェクトっぽいものに変換する機能。名前とメソッドシグネチャを含めて宣言を行う。new の引数にメソッドを渡してインスタンスを作成する。
delegate bool Filter(string s);

class Test {
static void Main() {
Filter f = new Filter(FirstHalfOfAlphabet);
Display(new String[] {"Ant", "Lion", "Yak"}, f);
}

static bool FirstHalfOfAlphabet(string s) {
return "N".CompareTo(s) > 0;
}

static void Display(string[] names, Filter f) {
int count = 0;
foreach(string s in names) {
if (f(s)) // デリゲートの呼び出し
Console.WriteLine("Item {0} is {1}", count++, s);
}
}
}

 デリゲートの += メソッドを使って、複数のメソッドの保存と呼び出しを行うことができる。
using System;
delegate void MethodInvoker();
class Test {
static void Main() {
new Test(); //=> "Foo", "Goo"
}
Test () {
MethodInvoker m = null;
m += new MethodInvoker(Foo);
m += new MethodInvoker(Goo);
}
void Foo() {
Console.WriteLine("Foo");
}
void Goo() {
Console.WriteLine("Goo");
}
}


以下、「C#エッセンシャルズ」には無い話。

C# 2.0 からは メソッドからデリゲートへの暗黙の変換が可能になったらしい。上の例は、こう書ける。
delegate bool Filter(string s);

class Test {
static void Main() {
Filter f = FirstHalfOfAlphabet; // 暗黙に変換
Display(new String[] {"Ant", "Lion", "Yak"}, f);
}

static bool FirstHalfOfAlphabet(string s) {
return "N".CompareTo(s) > 0;
}

static void Display(string[] names, Filter f) {
int count = 0;
foreach(string s in names) {
if (f(s)) // デリゲートの呼び出し
Console.WriteLine("Item {0} is {1}", count++, s);
}
}
}

匿名メソッド
 C# 2.0 から匿名メソッドというものが導入された、、、が、もっと便利な構文 (ラムダ式) が C# 3.0 から導入されたようなので、省略。

ラムダ式
基本形 (式形式)
(input parameters) => expression

 パラメータの括弧は、パラメータの数が1つの場合は省略可能。パラメータの型は、コンパイラによる型推論が可能な場合は省略可能。
x => x > 0;
(x, y) => return x + y;
(int x, string s) => s.Length > x

本体部分が複数のステートメントからなる場合は、中括弧でくくる (ステートメント形式)。
n => {
string s = n + " " + "World";
Console.WriteLine(s);
}

標準ジェネリックデリゲート
基本形
Func<TParam1, TParam2, ..., TResult>

TParam1やTParam2 に引数の型を、Tresult に返り値の型を指定する。これを使って、最初の例を書き直してみると、
class Test {
static void Main() {
Display(new String[] {"Ant", "Lion", "Yak"},
s => "N".CompareTo(s) > 0); // ここがラムダ式
}

// 標準ジェネリックデリゲートでラムダ式を受け取る
static void Display(string[] names, Func f) {
int count = 0;
foreach(string s in names) {
if (f(s)) // デリゲートの呼び出し
Console.WriteLine("Item {0} is {1}", count++, s);
}
}
}
最初の例と比べると、かなり簡潔に書けるようになった。

 Java陣営が、クロージャを導入するとかしないとか言っている間に (結局、JDK7 には入らないみたいだけど) C# の関数型機能がこんなに充実しているのに驚き。

参考:
デリゲート (C# によるプログラミング入門)
関数型言語由来の新機能 (C# によるプログラミング入門)
MSDN: Func(T, TResult) デリゲート (System)
[PR]
by fkmn | 2009-04-13 23:55 | IT
「C# エッセンシャルズ」まとめ その3

2.9.7 メソッド (p.51, 52)

・引数の値渡し/参照渡し
 デフォルトでは、C# の引数は値渡しされる。ref 修飾子を仮引数にしていすると、参照渡しになる。

static void Foo(int p) { ++p; }      // 値渡し
static void Bar(ref int p ) { ++p; } // 参照渡し
public static void Main() {
int x = 8;
Foo(x);
Console.WriteLine(x); //=> 8
Bar(x);
Console.WriteLine(x); //=> 9
}
 デフォルトが値渡しってのは、意外と珍しいかも。

・out修飾子
 メソッドから値を受け取るための引数を指定するための修飾子。メソッド内で変数に値を割り当てられる事が保証されるので、メソッド呼び出しの時点では初期化を行わなくても良い。
using System;
class Test {
static void Split(string name, out string firstNames,
out string lastName) {
int i = name.LastIndexOf(' ');
firstNames = name.Substring(0, i);
lastName = name.Substring(i + 1);
}

public static void Main() {
string a, b; // 初期化不要
Split("Nuno Bettencourt", out a, out b); // 呼び出し側でも out が必要
Console.WriteLine("FirstName: {0}, LastName: {1}", a, b);
//=> FirstName: Nuno, LastName: Bettencourt
}
}

 うーん、これは正直どうなんだろ。引数で結果を受け取るという機会が、Cならまだしも、C#ではほとんどないような気がするんだけど。少なくとも、僕は使わないだろうな。

・params修飾子
 params修飾子は、メソッドの最後のパラメータに指定することができる。これが指定されると、メソッドは、特定の方のパラメータをいくつでも受け取ることができる。
using System;
class Test {
static int Add(params int[] iarr) {
int sum = 0;
foreach (int i in iarr)
sum += i;
return sum;
}

static void Main() {
int i = Add(1, 2, 3, 4);
Console.WriteLine(i); //=> 10
}
}

 ruby の * が付いた仮引数みたいなものだね。ちなみに、Ruby 1.9 からは、* は最後以外の引数にも指定できるようになりました (って、いつの間にか ruby の話になってる・・・w)。
def add(*iarr, name)
sum = 0
sum = iarr.inject { |r, s| r += s }
return "sum: #{sum}, name: #{name}"
end

def main
puts add(1, 2, 3, 4, 'fkmn') #=> "sum: 10, name: fkmn
end

main()


2.9.9 インスタンスコンストラクタ (p.56, 57)

 クラス/構造体では、コンストラクタをオーバーロードする事が可能。thisキーワードを使うと、オーバーロードされたコンストラクタを呼び出すことができる。baseキーワードを使うと、親クラスのコンストラクタを呼び出すことができる。
class B {
public int x;
putlic B(int a) {
x = 1;
}
public B(int a, int b) {
x = a * b;
}
// クラスBのコンストラクタは、すべてパラメータを受け取る
}

class D : B {
public D() : this(7) {} // オーバーロードされたコンストラクタを呼び出す
public D(int a) : base(a) {} // 親クラスのコンストラクタを呼び出す
}

 構文にちょっと違和感を感じるけど、機能自体はまぁ普通、というか無いと困る。

2.10.5 明示的なインターフェイスの実装 (p.65)

 インターフェイスメンバとそのクラスまたは構造体の既存のメンバの名前が重複した場合は、競合を解決するために、インターフェイスのメンバを明示的に実装することができる。

public interface IDelete {
void Delete();
}

public interface IDesignTimeControl {
object Delete();
}

public class TextBox : IDelete, IDesignTimeControl {
void IDelete.Delete() { ... }
object IDesignTimeControl.Delete() { ... }
// 競合を解決するためには、片方だけを明示的に実装すれば十分
}

[PR]
by fkmn | 2009-04-10 23:55 | IT
「C# エッセンシャルズ」まとめ その2

2.9.5 プロパティ (p.47, 48)

 アクセサ (Java でいう getter や setter) を生成する機能。

public class Well {
decimal dollars; // private フィールド
public int Cents {
get { return(int)(dollars * 100); }
set {
if (value >= 0)
dollars = (decimal)value / 100;
}
}
}

class Test {
static void Main() {
Well w = new Well();
w.Cents = 25; // set
int x = w.Cents; // get
w.Cents += 10; // get と set
}
}
 get{} だけ定義すると読み取り専用、set{} だけ定義すると書き込み専用というように定義できる。

 プロパティは、MSIL (Microsoft Intermediate Language) の段階で、get_XXX や set_XXX に変換される、とのこと。
public int get_Cents {...}
public void set_Cents (int value) {...}

 したがって、上の例のように Cents というプロパティを定義しているクラスでは、(C# の段階で) get_Cents や set_Cents といったメソッドは作成できない (Visual C# 2008 Express Edition で確認)。
public class Well {
decimal dollars; // private フィールド
public int Cents {
get { return (int)(dollars * 100); }
set {
if (value >= 0)
dollars = (decimal)value / 100;
}
}

// ***** エラー!! *****
public int get_Cents() {
return (int)dollars;
}
}


2.9.6 インデクサ (p.48, 49)

 配列スタイルの [] 構文をつかって、オブジェクトにアクセサを生やす。コレクションをカプセル化するクラスの生成等に使える。
public class ScoreList {
int[] scores = new int[5];

// インデクサ
public int this[int index] {
get { return scores[index]; }
set {
if (value >= 0 && value <= 10)
scores[index] = value;
}
}

// プロパティ (読み取り専用)
public int Average {
get {
int sum = 0;
foreach (int score in scores)
sum += score;
return sum / scores.Length;
}
}
}

class IndexerTest {
static void Main() {
ScoreList sl = new ScoreList();
sl[0] = 9;
sl[1] = 8;
sl[2] = 7;
sl[3] = sl[4] = sl[1];
System.Console.WriteLine(sl.Average); //=> 8
}
}

 微妙に分かりにくい機能。obj[0] を obj.0 というプロパティに対する構文糖衣と考えると、少し分かりやすいかも。


次回へ続く。
[PR]
by fkmn | 2009-04-08 23:55 | IT
「C# エッセンシャルズ」まとめ その1
 「C#エッセンシャルズ」について、というよりも、C# そのものの言語仕様について、個人的に「おっ」と思った部分についてのまとめメモ。このペースでいくと、全3-4回ぐらいになりそう。

verbatim文字列リテラル (p.15)

 Stringリテラルの先頭に @ をつけると「verbatim文字列リテラル」として取り扱われる。\ などのエスケープ文字が含まれていても、そのままの内容として扱われる。

public void StringDemo() {
string a1 = "\\\\server\\fileshare\\helloworld.cs";
string a2 = @"\\server\fileshare\helloworld.cs";
Console.WriteLine(a1 == a2); //=> True

string b1 = "First Line\r\nSecond Line";
string b2 = "First Line
Second Line";
Console.WriteLine(b1 == b2); //=> True
}

 Perl や Ruby のシングルクォートで囲まれた文字列みたいなものか。


using ステートメント (p.32)

 ruby の ブロックを使った open みたいなことが C# でもできる。
using (FileStream fs = new FileStream(fileName, FileMode.Open)) {
// fs に対する処理
}

 usingステートメントを使うと、IDisposableインターフェースを実装する変数の Dispose メソッドが自動で呼び出される。
 上のコードは、次のコードと全く同じとの事。
FileStream fs = new FileStream(fileName, FileMode.Open);
try {
// fs に対する処理
}
finally {
if (fs != null)
((IDisopsable)fs).Dispose();
}


2.7.3 仮想関数メンバ (p.37, 38)

 オーバーライドされる関数メンバは「virtual」キーワードで宣言する。オーバーライドする側は「override」キーワードを指定する。
class Location {
// オーバーライドされる関数メンバ
public virtual void Display() {
Console.WriteLine(Name);
}
}

class URL : Location {
// Location クラスの Display メソッドをオーバーライド
public override void Display() {
// 先頭の http:// を切り捨て
Console.WriteLine(Name.Substring(7));
}
}



2.7.6 継承したメンバを隠す機能 (p.39, 40)

 new キーワードの、コンストラクタ呼び出し以外の機能。
using System;
class B {
public virtual void Foo() {
Console.WriteLine("In B.");
}
}

class D : B {
public override void Foo() {
Console.WriteLine("In D.");
}
}

class N : D {
// Dクラスの Fooメソッドを隠す
public new void Foo() {
Console.WriteLine("In N.");
}
}

class Test {
public static void Main() {
N n = new N();
n.Foo(); //=> "In N."
((D)n).Foo(); //=> "In D."
((B)n).Foo(); //=> "In D."
}
}

 ちょっと、使いどころがまだよくわからないな。


2.9.3 フィールド、2.9.4 定数 (p.45, 46)

 フィールドに readonly 修飾子をつけると、読み取り専用フィールドとなり、値を割り当てた後にそれを修正する事ができなくなる。「readonly」は実行時に評価される
class MyClass {
int x;
float y = 1, z = 2;
static readonly int MaxSize = 10;
}


 「const」で定数を宣言する。コンパイル時に評価され、暗黙的に静的になる。コンパイル時に評価されるので、コンパイラによる最適化が行われる。
public static double Circumference(double radius) {
return 2 * Math.PI * radius;
}
は、最適化されて、次のように評価される。
public static double Circumference(double radius) {
return 6.28318530717959 * radius;
}


次回へ続く。
[PR]
by fkmn | 2009-04-06 23:55 | IT


とあるWebアプリケーションエンジニアの日記
S M T W T F S
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
カテゴリ
以前の記事
ブログパーツ
リンク
検索
タグ
最新のトラックバック
プログラミングが「出来る..
from とりあえず9JP?
Genographic ..
from ナンジャモンジャ
ジュセリーノ
from ありの出来事
くちこみブログ集(ライフ..
from くちこみブログ集(ライフ)(..
以降、丁寧語で行こう!
from エッセイ的な何か
その他のジャンル
ファン
記事ランキング
ブログジャンル
画像一覧

fkmnの最近読んだ本 フィードメーター - フッ君の日常 あわせて読みたい AX