2015-03-08 48 views
0

我想下面的代码工作:将字符串转换成波长/值

(define fn.str "(lambda (x) (displayln x)") 
(define fn.callable (string->lambda fn.str)) 
; and then 2 next lines should be valid 
(fn.callable 123) 
(apply fn.callable '(321)) 

但最好我能得到是EVAL串并得到输出,而不是 我的目标是获得实际控股值(λ在这种情况下)。

在一般情况下,这也是预期的效果:

(define val.num "500") 
(define val.li "'(1 2 3)") 
(define val.fn "(λ (a) a)") 
(define num (string->value val.num)) ; => num is now holding 500 
(define li (string->value val.li)) ; => list '(1 2 3) 
(define fn (string->value val.fn)) ; => callable lambda 

也许我来到足够接近的解决方案,但它有难闻的气味。

更多信息:

  • 这些字符串从外部(文件/用户输入)进入了程序。
  • 提取/解析的值应绑定到某些内容(例如哈希表)以供进一步访问。
+0

也许相关:http://stackoverflow.com/questions/20349543/how-do-you-回到最描述-的-A-程序式的方案。虽然,如果你真的想要使用任意字符串并评估它们,你可能需要'eval'。如果可能的话,最好在Racket中制作自己的'#lang'。 – 2015-03-09 03:55:25

回答

2

你说得对 - 从字符串评估代码是一种糟糕的代码味道......也许有更好的方法来做你想做的事情。总之,这里是一个可能的解决方案:

(define-namespace-anchor a) 
(define ns (namespace-anchor->namespace a)) 

(define (eval-string str) 
    (eval (call-with-input-string str read) ns)) 

它的工作原理要求​​的采样输入:

(define fn.str "(lambda (x) (displayln x))") 
(define fn.callable (eval-string fn.str)) 
(fn.callable 123) 
=> 123 

(apply fn.callable '(321)) 
=> 321 

(define val.num "500") 
(eval-string val.num) 
=> 500 

(define val.li "'(1 2 3)") 
(eval-string val.li) 
=> '(1 2 3) 

(define val.fn "(λ (a) a)") 
(eval-string val.fn) 
=> #<procedure> 
+0

这样使用这个解决方案:'(hash-ref!h key(eval-str“(λ(x y)'(y x))”))'会导致数组不匹配。手动检查和“散列集!”在这里是更好的选择(可能很明显,但不适合我),至少使用这种方法。 – 2015-03-09 05:04:22

+0

@IskanderSharipov这听起来更像是一个问题,当你从哈希表中获得它时,实际上使用该函数的方式会有问题,而不是方法本身。 – 2015-03-09 16:25:08