2009年05月10日 23:21

PHPで先月の年と月の文字列を得る

PHPで前の月の年と月の文字列を得る方法のサンプル。"200905"というような文字列を取得できます。
$prev_month = date('Ym', strtotime(date('Ym') . '01') - 24*60*60);
タグ:PHP
カテゴリ:テック
2009/05/10 Sun 23:21 | Comment(0) | TrackBack(0) | テック | このブログの読者になる | 更新情報をチェックする

2009年05月09日 17:21

Rubyでディレクトリを再帰的に作成

Rubyでディレクトリを再帰的に作成するサンプル。作成しようとするディレクトリの親ディレクトリがなければ、必要なだけ作成する。
def mkdir2(path)
  return if FileTest.exist?(path);
  parent = File::dirname(path);
  mkdir2(parent);
  Dir::mkdir(path);
end

mkdir2(ARGV[0]);
タグ:ruby
カテゴリ:テック
2009/05/09 Sat 17:21 | Comment(2) | TrackBack(0) | テック | このブログの読者になる | 更新情報をチェックする

2009年05月09日 16:50

Rubyでディレクトリの中身を再帰処理

Rubyでディレクトリの中を再帰的にたどり、ファイルごとに特定の処理をするサンプル。ファイル名での並び替えもする。
def printDirs(dir)
  Dir::entries(dir).sort.each do |child|
    path = dir + "/" + child;
    if child == "." or child == ".."
      # do nothing
    elsif File::ftype(path) == "directory"
      printDirs(path, &Proc.new{|it| yield(it)})
    else
      yield(path)
    end
  end
end

printDirs(".") do |it|
  print(it + "\n");
end
タグ:ruby
カテゴリ:テック
2009/05/09 Sat 16:50 | Comment(1) | TrackBack(0) | テック | このブログの読者になる | 更新情報をチェックする

2009年05月09日 16:13

RubyでファイルのMD5を取得

RubyでファイルのMD5ハッシュ値を取得するサンプル。
require 'digest/md5'

print(Digest::MD5.hexdigest(File.open('hoge.txt', 'rb').read))
タグ:ruby
カテゴリ:テック
2009/05/09 Sat 16:13 | Comment(1) | TrackBack(0) | テック | このブログの読者になる | 更新情報をチェックする

2009年05月08日 20:29

PHPでUserAgentから携帯かどうか判定

PHPでUserAgentから携帯かどうかまたはキャリアを判定する方法のサンプル。
$ua = $_SERVER['HTTP_USER_AGENT'];

if (preg_match("/^DoCoMo\/2\.0/i", $ua)) { // DoCoMo FOMA (XHTML)
	$isMobile = true;
} else if (preg_match("/^DoCoMo\/1\.0/i", $ua)) { // DoCoMo MOVA
	$isMobile = true;
} else if (preg_match("/^SoftBank/i", $ua)) { // SoftBank
	$isMobile = true;
} else if (preg_match("/^(Vodafone|MOT-)/i", $ua)) { // Vodafone 3G
	$isMobile = true;
} else if (preg_match("/^J\-PHONE/i", $ua)) { // Vodafone 1G,2G
	$isMobile = true;
} else if (preg_match("/iPhone/i", $ua)) { // iPhone
	$isMobile = true;
} else if (preg_match("/^KDDI\-/i", $ua)) { // au (XHTML)
	$isMobile = true;
} else if (preg_match("/UP\.Browser/i", $ua)) { // au (HDML) TU-KA
	$isMobile = true;
} else if (preg_match("/WILLCOM/i", $ua) ||
           preg_match("/DDIPOCKET/i", $ua)){ // WILLCOM Air EDGE
	$isMobile = true;
} else if (preg_match("/^PDXGW/i", $ua)) { // WILLCOM EDGE LINK
	$isMobile = true;
} else if (preg_match("/^(L\-mode)/i", $ua)) { // L-mode
	$isMobile = true;
} else {
	$isMobile = false;
}
タグ:PHP
カテゴリ:テック
2009/05/08 Fri 20:29 | Comment(0) | TrackBack(0) | テック | このブログの読者になる | 更新情報をチェックする

2009年04月26日 23:56

JavaScriptからJavaアプレットのJavaメソッドを呼び出す

Deployment Toolkit を使ってJavaアプレットをHTMLに貼り付け、JavaScriptからJavaへの通信を使ってJavaで書かれたアプレットのメソッドを呼び出そうとしても、not a function などとJavaScriptがエラーを出していて、困っていたら、単にタイミングの問題だった。

アプレットを貼り付ける Deployment Toolkit を使ってアプレットを貼り付け、HTML上でそのあとでJavaのメソッドを呼び出すと、IE6では成功し、Firefox3では成功するときとエラーになるときとあり、GoogleChromeだと常にエラーになってしまった。GoogleだとJavaScriptは速くていいのだがAppletの実装が中途半端なのか、とあきらめていたが、ページをロードしてから1秒後にメソッドを呼び出すようにしてみたら、どのブラウザでも常に成功するようになった。アプレットのロードが完了しないとメソッドの呼び出しに成功しないのは当然かと。

しかし、最初IE6では常に成功し、GoogleChromeでは常にエラーで、Firefox3ではその中間というのは、まさにJavaScriptの実行の速度を反映しているのかと、思った。
カテゴリ:テック
2009/04/26 Sun 23:56 | Comment(0) | TrackBack(0) | テック | このブログの読者になる | 更新情報をチェックする

2009年03月29日 01:05

ブログに数式を書く方法(formula)

ブログに数式を載せる方法をいろいろ探していたら、formulaというサービスがあることを知りました。使い方はこちら

imgのsrc属性に数式のLaTeX表現をURLエンコードして書かなければいけないのですが、面倒なので、JavaScriptで動的にsrcを生成できるスクリプトを書きました。jQueryを使っています。

<script type="text/javascript" src="http://********/common/jquery.js"></script>
<script type="text/javascript">
	$("#content").ready(function(){
		$(".formula").each(function(){
			var alt = this.getAttribute("alt");
			var v = encodeURI(alt)
			this.setAttribute("src", "http://formula.s21g.com/?" + v + ".png");
			this.setAttribute("border", "0");
			$(this).wrap("<a href=\"http://formula.s21g.com/?" + v + "\" target=\"_blank\"></a>");
		});
	});
	$(function(){
		dp.SyntaxHighlighter.HighlightAll('code');
	});
</script>

jQueryをサーバにアップし、参照できるようにします。上のスクリプトの ****** となっている箇所は適当に書き換えてください。imgのalt属性に数式をLaTeX形式で記述し class="formula" とすれば、自動的にsrc属性を設定し、このformulaの利用条件であるリンクもaタグで囲んで自動的に画像からリンクします。

<img class="formula" alt="e^{i\pi}=-1" />

と書けば、

e^{i\pi}=-1

と表示されます。

→使用例
カテゴリ:テック
2009/03/29 Sun 01:05 | Comment(0) | TrackBack(1) | テック | このブログの読者になる | 更新情報をチェックする

2009年01月13日 00:02

URIの仕様

Uniform Resource Identifier (URI) の構文規則を調べました。以下、あえて厳密には書かずに、一部省略もしつつ、おおざっぱな説明です。

scheme ":" "//" [ [ userinfo "@" ] host [ ":" port ] ] path [ "?" query ] [ "#" fragment ]

scheme:アルファベットから始まり、アルファベット、数字、"+", "-", "." で構成される。大文字・小文字の区別はしないが小文字が標準。

userinfo:アルファベット、数字、"-", ".", "_", "~", "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "=", ":"、パーセントエンコードされた文字で構成され、host に比べ ":" が許容されている。

host:ホスト名、IPv4、"[" "]" で囲まれたIPv6のいずれかの書式。ホスト名はアルファベット、数字、"-", ".", "_", "~", "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="、パーセントエンコードされた文字で構成される。

port:数字。

path:"/" で始まり、0個以上の segment が "/" で区切られて構成される。最後は segment または "/"。host が省略されている場合は、先頭が2個以上連続する "/" であってはならないが、それ以外の場合または場所では "/" が2個以上連続してもよい。segment はアルファベット、数字、"-", ".", "_", "~", "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "=", ":", "@"、パーセントエンコードされた文字で構成され、host に比べ ":", "@" が許容されている。

query:アルファベット、数字、"-", ".", "_", "~", "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "=", ":", "@", "/", "?"、パーセントエンコードされた文字で構成され、path に比べ "/", "?" が許容されている。

fragment:query と同じで、アルファベット、数字、"-", ".", "_", "~", "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "=", ":", "@", "/", "?"、パーセントエンコードされた文字で構成される。

許容されていない文字を使いたい場合は、パーセントエンコードをする。アルファベット、数字、"-", ".", "_", "~" はパーセントエンコードをしなくてもよい。

http://abc.com/def/
http://abc.com/de%66/
の2つのURIは等価であり、アルファベットはエンコードしなくてもよいのであるから1つ目の記法が望ましい。

http://abc.com/def/
http://abc.com/def%2f
の2つのURIは厳密にはURIとしては等価ではない。"/" は segment の中では許容されていない文字なので、エンコードしていない場合は区切り子として解釈されてしまうが、エンコードされた場合は segment の一部として解釈される。

http://abc.com/def/?ghi
http://abc.com/def/%3fghi
の2つもURIとしては等価ではない。1つ目は "?" の後が query として解釈されるが、2つ目は path の一部として解釈される。

参考にしたページ:RFC3986

カテゴリ:テック
2009/01/13 Tue 00:02 | Comment(0) | TrackBack(0) | テック | このブログの読者になる | 更新情報をチェックする

2008年12月09日 00:15

Java Rhino のスクリプト実行を中断する方法

JavaのJavaScript実装であるRhinoで、スクリプトを実行開始後、一定の時間が経過したら強制的にスクリプト実行を中断する方法を探りました。Java SE 6 に標準で用意されている JSR-223: Scripting for the Java Platform (javax.scriptパッケージ) では、それらしきAPIが見つからなかったので、
http://www.mozilla.org/rhino/download.html
より rhino1_7R1.zip をダウンロードして探ってみました。

Context#exit() というメソッドがありましたので、試してみました。

import java.io.IOException;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;

public class Test {
	
	private static Context _cx = null;
	
	public static void main(String[] args) throws IOException, InterruptedException {
		
		final Context cx = Context.enter();
		try {
			Runnable runnable = new Runnable(){
				public void run(){
					Scriptable scope = cx.initStandardObjects();
					String source = "var ii = 1; while(true){java.lang.System.out.println(ii);java.lang.Thread.sleep(1000);ii++};";
					Object result = cx.evaluateString(scope, source, "sample", 1, null);
					System.out.println(result);
				}
			};
			Thread thread = new Thread(runnable);
			thread.start();
			Thread.sleep(10000);
		} finally {
			cx.exit();
		}
		
	}
	
}

Exception in thread "Thread-0" java.lang.RuntimeException: No Context associated with current Thread
	at org.mozilla.javascript.Context.getContext(Context.java:2206)
	at org.mozilla.javascript.SecurityController.createLoader(SecurityController.java:136)
	at org.mozilla.javascript.optimizer.Codegen.defineClass(Codegen.java:143)
	at org.mozilla.javascript.optimizer.Codegen.createScriptObject(Codegen.java:102)
	at org.mozilla.javascript.Context.compileImpl(Context.java:2293)
	at org.mozilla.javascript.Context.compileString(Context.java:1240)
	at org.mozilla.javascript.Context.compileString(Context.java:1229)
	at org.mozilla.javascript.Context.evaluateString(Context.java:1085)
	at Test$1.run(Test.java:18)
	at java.lang.Thread.run(Unknown Source)

だめでした。Context#enter() を呼び出したスレッドでスクリプトを実行しなきゃいけないようです。

import java.io.IOException;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;

public class Test {
	
	private static Context _cx = null;
	
	public static void main(String[] args) throws IOException, InterruptedException {
		
		Runnable runnable = new Runnable(){
			public void run(){
				Context cx = Context.enter();
				_cx = cx;
				try {
					Scriptable scope = cx.initStandardObjects();
					String source = "var ii = 1; while(true){java.lang.System.out.println(ii);java.lang.Thread.sleep(1000);ii++};";
					Object result = cx.evaluateString(scope, source, "sample", 1, null);
					System.out.println(result);
				} finally {
					cx.exit();
				}
			}
		};
		Thread thread = new Thread(runnable);
		thread.start();
		Thread.sleep(10000);
		_cx.exit();
		
	}
	
}

Exception in thread "main" java.lang.IllegalStateException: Calling Context.exit without previous Context.enter
	at org.mozilla.javascript.Context.exit(Context.java:436)
	at Test.main(Test.java:29)

これもだめでした。Context#exit() も同じスレッドで呼び出さなくてはいけないようです。

ContextFactory#observeInstructionCount というメソッドを見つけました。ContextFactory のサブクラスを作ればよいようです。

import org.mozilla.javascript.Callable;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.Scriptable;

public class Test {
	
	private static Context _cx = null;
	
	public static void main(String[] args){
		
		Context cx = Context.enter();
		try {
			Scriptable scope = cx.initStandardObjects();
			String source = "var ii = 1; while(true){java.lang.System.out.println(ii);java.lang.Thread.sleep(1000);ii++};";
			Object result = cx.evaluateString(scope, source, "sample", 1, null);
			System.out.println(result);
		} finally {
			Context.exit();
		}
		
	}
	
	static {
		ContextFactory.initGlobal(new MyContextFactory());
	}
	
	static class MyContextFactory extends ContextFactory {
		
		@Override
		protected Context makeContext(){
			MyContext cx = new MyContext();
			// cx.setOptimizationLevel(-1);
			cx.setInstructionObserverThreshold(1000);
			return cx;
		}
		
		@Override
		protected void observeInstructionCount(Context cx, int instructionCount){
			MyContext mcx = (MyContext)cx;
			long curr = System.currentTimeMillis();
			if(curr >= mcx.startTime + 10000){
				throw new Error();
			}
		}
		
		@Override
		protected Object doTopCall(Callable callable, Context cx,
				Scriptable scope, Scriptable thisObj, Object[] args){
			MyContext mcx = (MyContext)cx;
			mcx.startTime = System.currentTimeMillis();
			return super.doTopCall(callable, mcx, scope, thisObj, args);
		}
		
	}
	
	static class MyContext extends Context {
		
		long startTime;
		
	}
	
}

Exception in thread "main" java.lang.Error
	at Test$MyContextFactory.observeInstructionCount(Test.java:45)
	at org.mozilla.javascript.Context.observeInstructionCount(Context.java:2135)
	at org.mozilla.javascript.Interpreter.addInstructionCount(Interpreter.java:4639)
	at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:3916)
	at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2484)
	at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:162)
	at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:401)
	at Test$MyContextFactory.doTopCall(Test.java:54)
	at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3003)
	at org.mozilla.javascript.InterpretedFunction.exec(InterpretedFunction.java:173)
	at org.mozilla.javascript.Context.evaluateString(Context.java:1088)
	at Test.main(Test.java:18)

これでできるようです。10秒経過したところで、Errorがスローされました。

cx.setOptimizationLevel(-1) はなくてもよいし、cx.setOptimizationLevel(9) でも、ちゃんと10秒後に例外がスローされました。

追記:最適化されていても中断できるのは、Rhino 1.7 からの機能のようでした。
https://developer.mozilla.org/en/New_in_Rhino_1.7R1
https://bugzilla.mozilla.org/show_bug.cgi?id=397680

2009/12/01追記
Beanshellの場合
http://hydrocul.seesaa.net/article/134455692.html
カテゴリ:テック
2008/12/09 Tue 00:15 | Comment(0) | TrackBack(1) | テック | このブログの読者になる | 更新情報をチェックする
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。