本科时软件工程课学习了C#。最近有兴致再学习一下。Visual Studio虽然好用,但是太重了。
决定使用轻量级的 .Net IDE SharpDevelop来写代码。当然,用文本编辑器配合C#编译器学习也是可以的。
蜜月之旅
老婆精心计划的蜜月之旅。目的地是她梦寐以求的意大利。我们申请签证的目的地是希腊,然后借助申根签证去意大利。Emirates官网买的机票,在迪拜呆一晚上逛逛。然后飞去雅尼的故乡—希腊。在雅典逛一下后,搭乘爱琴海航空飞机直飞圣托里尼(Santorini)。
结束希腊这部分的路程后,就是蜜月旅行的重头戏:意大利。先去米兰,然后威尼斯,佛罗伦萨。然后搭乘火车去比萨、卢卡,当日返回佛罗伦萨。第二天一早租车自驾横穿托斯卡纳大区。然后从丘西乘火车前往罗马。
Java1.6.0 Minimal Distribution
使用PaxScript为Delphi应用增加对脚本的支持
通过使用PaxScript可以为Delphi应用增加对脚本的支持。
PaxScript支持paxC,paxBasic,paxPascle,paxJavaScript(对ECMA-262做了扩展) 四种脚本语言。它们分别是对应语言的子集。
在为程序增加脚本支持时要解决的主要问题是:本地代码与脚本之间的互相调用。
PaxScript为四种脚本语言都增加的名字空间和模块的概念。某段代码必须属于某个名字空间。执行代码时要指定代码所属的模块。默认的名字空间是全局名字空间。
Phi中使用DFM文件
Delphi中有将窗体持续化的函数
- ObjectBinaryToText: 将二进制object流转换为文本格式
- ObjectResourceToText:将Windows资源对象流转换为文本格式
- ObjectTextToBinary:将文本格式对象流转换为二进制格式
- ObjectTextToResource:将文本格式对象流转换为Windows资源格式
Phi中可以加载一个DFM文件,然后动态创建DFM对应的窗体。这样就不用手工敲代码创建了。只不过DFM只能包含Phi中的控件。
破解Sublime弹出购买对话框
用ollydbg搜索purchase,找到下面的地方。将call用nop填充。保存exe。
某个版本Chrome中的undefined
昨天百度新闻的同事让我帮忙排查一下线上问题,最终问题定位到这样一段代码:
if (window.varname === undefined) {
...
}
左侧是Chrome,右侧是Firefox
所以不要写这样的代码
if (window.xxxxxx === undefined) {...}
要写成
if (typeof window.xxxxx === "undefined" ) {....}
Setup node.js and packages for Windows
http://nodejs.org/ 上已经有多个版本的node.js for windows 的单个可执行文件.体积都很大.
有个问题至今未解决就是还没有好的npm for windows.
在npm for windows出来之前我们可以用下面的方法解决:
思路类似rubygems
按下面目录结构组织node.exe.
将bin目录加到%path%中
将各种module放到node_modules目录下,如果没有描述文件package.json,还需要手工建立
这样就可以直接在node中require(module_name)了
一般从github上下载下来的zip直接解压到node_modules下,把目录名改为模块名就ok了
更新 21:50 2011-11-14
npm已经可以顺利在windows安装了.参见官方文档
v8js引擎常用C++代码片段
/***********************************************/ /** Embedder's Guide */ /** http://code.google.com/apis/v8/embed.html **/ /***********************************************/ /** * Constant **/ v8::True(); v8::False(); v8::Null(); v8::Undefined(); /** * Some classes **/ v8::Boolean v8::Array v8::Arguments v8::Date v8::Function v8::Int32 v8::Integer v8::Number v8::Object v8::Regexp v8::Primitive v8::Script v8::String v8::Uint32 v8::TryCatch v8::V8 /** * Function signature **/ static v8::Handle<v8::Value> FUNCTION(const v8::Arguments& args); /** * Set simple property **/ process->Set(String::NewSymbol("platform"), String::New(PLATFORM)); /** * Return object **/ Handle<Object> NewObj(int x) { HandleScope handle_scope; Handle<Object> obj = Object::New(); obj->Set(String::NewSymbol("name"), Integer::New(x)); return handle_scope.Close(obj);} /** * Return array **/ Handle<Array> NewPointArray(int x, int y, int z) { // We will be creating temporary handles so we use a handle scope. HandleScope handle_scope; // Create a new empty array. Handle<Array> array = Array::New(3); //if can not determine the length of the array just left first parameter empty Handle<Array> array = Array::New(); // Return an empty result if there was an error creating the array. if (array.IsEmpty()) return Handle<Array>(); // Fill out the values array->Set(0, Integer::New(x)); array->Set(1, Integer::New(y)); array->Set(2, Integer::New(z)); // Return the value through Close. return array; //ERROR // The Close method copies the value of its argument into the enclosing scope // return handle_scope.Close(array); } /** * Accessor * accessor callbacks are invoked when a specific object property is accessed by a script **/ Handle<ObjectTemplate> global_templ = ObjectTemplate::New(); global_templ->SetAccessor(String::New("x"), XGetter, XSetter); global_templ->SetAccessor(String::New("y"), YGetter, YSetter); Handle<Value> XGetter(Local<String> property, const AccessorInfo& info) { return Integer::New(x); } void XSetter(Local<String> property, Local<Value> value, const AccessorInfo& info) { x = value->Int32Value(); } /** * Interceptor * interceptor callbacks are invoked when any object property is accessed by a script * named property interceptors - called when accessing properties with string names. * ndexed property interceptors - called when accessing indexed properties. **/ Local<ObjectTemplate> envTemplate = ObjectTemplate::New(); envTemplate->SetNamedPropertyHandler(EnvGetter, EnvSetter, EnvQuery, EnvDeleter, EnvEnumerator, Undefined()); Local<Object> env = envTemplate->NewInstance();process->Set(String::NewSymbol("env"), env); //Getter static Handle<Value> EnvGetter(Local<String> property, const AccessorInfo& info) { String::Utf8Value key(property); const char* val = getenv(*key); if (val) { HandleScope scope; return scope.Close(String::New(val)); } return Undefined(); } //Setter static Handle<Value> EnvSetter(Local<String> property, Local<Value> value, const AccessorInfo& info) { String::Utf8Value key(property); String::Utf8Value val(value); #ifdef __POSIX__ setenv(*key, *val, 1); #else __WIN32__ NO_IMPL_MSG(setenv) return value; } //Query static Handle<Integer> EnvQuery(Local<String> property, const AccessorInfo& info) { String::Utf8Value key(property); if (getenv(*key)) { HandleScope scope; return scope.Close(Integer::New(None)); } return Handle<Integer>(); } //Deleter static Handle<Boolean> EnvDeleter(Local<String> property, const AccessorInfo& info) { String::Utf8Value key(property); if (getenv(*key)) { #ifdef __POSIX__ unsetenv(*key); #else NO_IMPL_MSG(unsetenv) #endif return True(); } return False(); } //Enumerator static Handle<Array> EnvEnumerator(const AccessorInfo& info) { HandleScope scope; int size = 0; while (environ[size]) size++; Local<Array> env = Array::New(size); for (int i = 0; i < size; ++i) { const char* var = environ[i]; const char* s = strchr(var, '='); const int length = s ? s - var : strlen(var); env->Set(i, String::New(var, length)); } return scope.Close(env); } /** * Create function object and set it's properties **/ /** * Exception **/ TryCatch trycatch; Handle v = script->Run(); if (v.IsEmpty()) { Handle<value> exception = trycatch.Exception(); String::AsciiValue exception_str(exception); printf("Exception: %s\n", *exception_str); // ... } if (args.Length() < 3 || !args[0]->IsString() || !args[1]->IsInt32() || !args[2]->IsInt32()) { return ThrowException( Exception::TypeError(String::New("Bad argument"))); } /** * prototype **/ Handle<FunctionTemplate> biketemplate = FunctionTemplate::New(); biketemplate.PrototypeTemplate().Set( String::New("wheels"), FunctionTemplate::New(MyWheelsMethodCallback)) /** * Inheritance **/ void Inherit(Handle<FunctionTemplate> parent);biketmplate.Inherit(transportTemplate); /** * Parameter conversion **/ //int64 int n = args[0]->IntegerValue(); return scope.Close(Number::New(n)); //int32 int n = args[0]->Int32Value(); //double double d = args[0]->NumberValue(); //uint32 unsigned int ui = args[0]->Uint32Value(); //const char* v8::String:Utf8Value str(args[0]); const char* cstr = *str ? *str : NULL;
改写Array.prototype.toString
天在join(“”)一个Array的时候遇到一个问题:
当Array中还有Array的时候,嵌套的Array仍然会用逗号连接,而不是指定的空字符。比如
[1,[2,3],4].join("")
的结果是12,34
这不是我想要的。我希望得到1234
首先想到的解决办法就是递归遍历数组,如果元素是数组则对其调用join(“”)。
然后转念一想,递归调用的过程就是Array.prototype.join
本身啊。我只需改写Array.prototype.toString
就OK了
这是第一个版本:其问题是,如果忘记调用restore或连续调用两次Bakup就完蛋了。
var Bakup = (function(G) { var old = null; return function(who, name, to) { old = who.prototype[name]; who.prototype[name] = to; arguments.callee.restore = function() { who.prototype[name] = old; }; }; })(); var tag = ["<", "a ", ["href", "=\"", "http://localhost", "\""], ">"]; Bakup(Array, "toString", function() { return this.join(""); }); print(tag); Bakup.restore(); print(tag); Bakup(Array, "toString", function() { return this.join("-"); }); print(tag); Bakup.restore(); print(tag);
这是第二个版本:
function Bakup(who, name, to, callback) { var old = who.prototype[name]; who.prototype[name] = to; callback(); who.prototype[name] = old } var tag = ["<", "a ", ["href", "=\"", "http://localhost", "\""], ">"]; Bakup(Array, "toString", function() { return this.join(""); }, function() { print(tag); }); print(tag); Bakup(Array, "toString", function() { return this.join("-"); }, function() { print(tag); }); print(tag);