Clojure副作用

时间:2017-12-15 09:51:17

标签: clojure

我想知道这是否是关于副作用的良好做法。

最初代码是这样的:

<?php
    $dbhost = 'localhost';
    $dbuser = 'root';
    $dbpass = '';
    $conn = mysql_connect($dbhost, $dbuser, $dbpass);
    $response=array();
    if(! $conn ) {
        die('Could not connect: ' . mysql_error());
    }
        echo '';
        mysql_select_db('dbname');

        $moduleid = $_POST['module_id'];
        $selected_id=$_POST['selected_id']; //get the selected id here
        $sql= mysql_query("SELECT title FROM table WHERE  module_id='$moduleid'");


        $html = '<div>';
        $i = 1 ;
        if( $sql === FALSE ) {
            trigger_error('Query failed returning error: '. mysql_error(), E_USER_ERROR);
        } else {
            while($row = mysql_fetch_array($result)){
                $title = $row['title'];

                $html .= "<span class='head'>"<?php echo $title ; ?> " :</span><span>"" mins</span><br/>";
                $i++;
            }
        }
    $html .= '</div>';
    $response['html']=$html;
    $response['selected_id']=$selected_id;
    echo json_encode($response); 
    exit;

?>

但是我想添加一些日志记录然后返回库存,我想到了这个:

(defn grab [item]
  (if (in-stock? item) 
    (swap! inventory update-in [item] dec)))

工作正常。 “做”对于这种用途是正确的吗?类似案件还有其他做法吗?

谢谢, R上。

1 个答案:

答案 0 :(得分:4)

这里没有任何罪恶。对于那些使用Python或Ruby等现代命令式语言来到Clojure的人来说,这种代码风格很常见。

为了使这个代码更像Clojure,你最好避免将状态保持在原子中。只需编写几个接受库存作为地图的函数,并返回一个新地图而不会破坏前一个地图。

(defn grap [inv item]
  (update inv item dec))

您可以在调用具有新旧状态库存的grab的过程中添加日志记录:

(def inv-old {:cola 10})

(let [inv-new (grap inv-old :cola)]
  (log "it was %s" inv-old)
  (log "now it's %s" inv-new))

几乎总是可以避免在代码中使用原子。