我遇到了一个问题,我正在寻找有关解决它的最佳方法的想法。
我接手开发了一个网站,该网站的后端是用 Perl 编写的,前端则大量使用 javascript。
客户端定期从后端接收数百个跟踪对象的更新。这些对象通过 javascript 映射到谷歌地图上。对象哈希(由 javascript 解析)包含有关对象的大量信息,例如位置、描述和各种状态变量。
有些数据是字符串形式,有些是数字形式。
问题是,在将数据推送到客户端 javascript 的过程中,所有值都变成了字符串。因此,在 javascript 中,例如,如果我测试一个值是否为正,即使该值为 0,测试也会成功,因为该值实际上是“0”而不是 0。
在服务器端,数据使用JSON::XS编码如下;
sub process_json {
my $self = shift;
return if( $self->{processed} );
$self->{processed} = 1;
if( $self->{requestrec}->status =~ /^3/ )
{
return $self->{requestrec}->status;
}
$self->{data}->{session} = {
id => $self->session->id,
user => $self->session->{data}->{__user},
};
use utf8;
my $output;
eval { $output = JSON::XS->new->utf8->encode( $self->{data} ); };
if($@)
{
use Carp;
confess($@);
}
$self->discard_request_body();
$self->req->content_type('application/json; charset=utf-8');
$self->req->headers_out->set( 'Expires' => 'Thu, 1 Jan 1970 00:00:00 GMT' );
my $out_bytes = encode( 'UTF-8', $output );
$self->req->headers_out->set( 'Content-Length' => length $output );
$self->req->print($output) unless( $self->req->header_only() );
delete $self->{session}->{data}->{errors}
if( exists $self->{session}->{data}->{errors} );
delete $self->{session}->{data}->{info}
if( exists $self->{session}->{data}->{info} );
} ## end of: sub process_json
在客户端,数据使用JSON.parse解码如下;
function http_process (req, callback, errorfn) {
if (req.readyState == 4) {
this.activerequest = null;
if (req.status != 200 && req.status != 0 && req.status != 304 && req.status != 403) {
if (errorfn) { return errorfn(req); } else { dialogue("Server error", "Server error " + req.status); }
if (req.status == 400) { dialogue("ERROR","Session expired"); this.failed = 1;
} else if (req.status == 404) { dialogue("ERROR", "Server error (404)"); this.failed = 1;
} else if (req.status == 500) { dialogue("ERROR", "Server error (500)"); this.failed = 1; }
} else {
if (callback) {
if (req.responseText) {
lstatus("Loaded (" + req.responseText.length + " bytes)");
warn("Received " + req.responseText.length + " bytes");
try {
var obj = JSON.parse(req.responseText);
} catch(e) {
warn(e);
warn(req.responseText);
}
callback( obj );
} else {
callback({});
}
}
}
}
谁能找到解决这个问题的有用方法? Perl 不是强类型的,JSON::XS 只是将数字数据解析为字符串而不是数字。我试图向 JSON.parse 添加一个 reviver(请参见下面的代码)- 但是它不起作用(它正确处理了大部分数据,但一直失败并显示各种消息,例如 non_object_property_call 或 undefined_method。
无论如何,如果在服务器端处理解析数据以确保正确类型的工作会更好。任何人都可以看到如何有效地实现这一点吗?
function toNum(key, value) {
/*make sure value contains an integer or a float not a string */
/*TODO: This seems VERY inefficient - is there a better way */
if (value instanceof Object) return;
if (value instanceof Array) return;
var intRE = /^\d+$/;
var floatRE = /^\d*\.\d+$/;
if(value.match(intRE)) {
value = parseInt(value);
return value;
}
if(value.match(floatRE)) {
value = parseFloat(value);
return value;
}
最佳答案
Simple Perl scalars (any scalar that is not a reference) are the most difficult objects to encode: JSON::XS and JSON::PP will encode undefined scalars as JSON null values, scalars that have last been used in a string context before encoding as JSON strings, and anything else as number value ...
诀窍是在编码之前将要编码的任何值“数字化”为数字。
$ perl -MJSON -e '$x="5"; print JSON->new->encode( [ $x, "$x", 0+$x ] )'
["5","5",5]
关于javascript - 类型转换 perl、javascript、JSON.parse JSON::XS - 需要想法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9252358/
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]
这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[
我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)