json - Ruby Sinatra JSON 设置
问题描述
我在 Sinatra 中写了这个扩展:
#extension.rb
require 'sinatra/base'
require 'json'
module Sinatra
module Ibaf
module Helpers
def test
payload = settings.my_json.dup
payload["test"] << "DONE"
puts payload
"OK"
end
end
def self.registered(app)
app.helpers Ibaf::Helpers
app.set :my_json, JSON.parse('{"test":[]}')
app.get "/" do
test
end
end
end
register Ibaf
end
和 myapp.rb
#app.rb
require 'sinatra'
require './extension.rb'
并作为 jruby -S app.rb -p 80 运行
在第一次调用http://localhost时,payload
变量包含一个元素"DONE"
。
第二次调用payload
包含两个元素,为什么?
我期望settings.my_json.dup
返回新对象,为什么要修改?
这是输出:
== Sinatra (v2.0.0) has taken the stage on 80 for development with backup from T
rinidad
Deploying from C:/Users/adminlocale/Desktop as /
Initializing ProtocolHandler ["http-bio-127.0.0.1-80"]
Starting ProtocolHandler ["http-bio-127.0.0.1-80"]
{"test"=>["DONE"]}
127.0.0.1 - [16/Oct/2018:17:08:42 +0200] "GET / " 200 2 0.1110
{"test"=>["DONE", "DONE"]}
127.0.0.1 - [16/Oct/2018:17:08:51 +0200] "GET / " 200 2 0.0250
解决方案
您正在浅复制哈希。这意味着你payload
有一个新的object_id
,但payload["test"]
仍然指向同一个对象。
[2] pry(#<Sinatra::Application>)> settings.my_json["test"].object_id
=> 47444101678660
[3] pry(#<Sinatra::Application>)> settings.my_json.dup["test"].object_id
=> 47444101678660
如果你想深度克隆(有几种方法可以做到):
[5] pry(#<Sinatra::Application>)> payload = Marshal.load(Marshal.dump(settings.my_json))
=> {"test"=>[]}
[6] pry(#<Sinatra::Application>)> payload["test"].object_id
=> 70216811281680
推荐阅读
- javascript - 是否有任何可能的保存 web html 并从中恢复?
- javascript - 用forEach循环转换JS中的数据结构
- regex - RewriteCond 和 regexp 以防止 Hotlink
- python - 使用熊猫绘制excel数据
- javascript - 使用 Jquery 在列表中包装多级标题(h1 h2 h3)
- javascript - setTimeout - 回调参数必须是一个函数
- google-cloud-platform - 即使存在配额,Google Compute Engine 也找不到 GPU
- java - 如何在java中找到用户接受的字符串数组的索引?
- javascript - 选择多行Jquery
- pandas - Python - 重复列以查找数据 df pandas