使用erlang的动态执行编写DSL
今天看到Erlang 动态执行和erlang动态解释,
实验的代码如下:
-module(dsl).-compile([export_all]).broker() -> receive {buy, Quantity, Ticker} -> % 向外部系统下单的具体代码放在这里 % Msg = "Order placed: buying ~p shares of ~p~n", io:format(Msg, [Quantity, Ticker]), broker(); {sell, Quantity, Ticker} -> % 向外部系统下单的具体代码放在这里 % Msg = "Order placed: selling ~p shares of ~p~n", io:format(Msg, [Quantity, Ticker]), broker() end.load_biz_rules(Pid, File) -> {ok, Bin} = file:read_file(File), Rules = string:tokens(erlang:binary_to_list(Bin), "\n"), [rule_to_function(Pid, Rule) || Rule <- Rules].rule_to_function(Pid, Rule) -> {ok, Scanned, _} = erl_scan:string(Rule), [{_,_,Action},{_,_,Quantity},_,_|Tail] = Scanned, [{_,_,Ticker},_,_,_,{_,_,Operator},_,{_,_,Limit}] = Tail, to_function(Pid, Action, Quantity, Ticker, Operator, Limit).to_function(Pid, Action, Quantity, Ticker, Operator, Limit) -> fun(Ticker_, Price) -> if Ticker =:= Ticker_ andalso ( ( Price < Limit andalso Operator =:= less ) orelse ( Price > Limit andalso Operator =:= greater ) ) -> Pid ! {Action, Quantity, Ticker}; % place an order true -> erlang:display("no rule applied") end end.apply_biz_rules(Functions, MarketData) -> lists:map(fun({Ticker,Price}) -> lists:map(fun(Function) -> Function(Ticker, Price) end, Functions) end, MarketData),ok.用到的biz_rules.txt内容如下:
[root@dev-emp-com work]# erlErlang R14B (erts-5.8.1) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]Eshell V5.8.1 (abort with ^G)1> Pid = spawn(fun() -> dsl:broker() end). <0.34.0>2> 2> Functions = dsl:load_biz_rules(Pid, "biz_rules.txt").[#Fun<dsl.0.70661670>,#Fun<dsl.0.70661670>, #Fun<dsl.0.70661670>]3> MarketData = [{'GOOG', 498}, {'MSFT', 30}, {'AAPL', 158}].[{'GOOG',498},{'MSFT',30},{'AAPL',158}]4> dsl:apply_biz_rules(Functions, MarketData)."no rule applied""no rule applied""no rule applied""no rule applied""no rule applied""no rule applied""no rule applied"Order placed: buying 9000 shares of 'GOOG'okOrder placed: buying 7000 shares of 'AAPL'5>