You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl解码含换行符的JSON文件为何需使用中间变量?

Perl中File::Slurp与decode_json链式调用的坑

问题现象

用Perl处理JSON文件时遇到一个奇怪的情况:

  • 将read_file的结果先存入变量,再传给decode_json,带换行的JSON文件能正常解析;
  • 直接链式调用decode_json(read_file('test.json'))时,会抛出JSON解析错误。

示例代码:

use v5.38;
use warnings;
use strict;

use File::Slurp qw( read_file );
use JSON        qw( decode_json );

# 正常运行的写法
my $contents = read_file('test.json');
my $decoded  = decode_json($contents);
say "Decoded contents";

# 报错的写法
my $chained_decoded = decode_json( read_file('test.json') );
say "Decoded chained contents";

测试用带换行的JSON文件内容:

[
    { "a": "b" },
    { "b": "c" }
]

报错信息:

, or ] expected while parsing array, at character offset 2 (before "(end of string)") at test.pl line 12.

原因解析

核心问题出在Perl的上下文机制,以及File::Slurp的read_file对上下文的响应:

  • 当read_file处于标量上下文(比如赋值给单个变量my $contents = ...)时,它会返回整个文件的内容作为单个字符串,这正是decode_json需要的完整JSON数据。
  • 当read_file处于列表上下文(比如直接作为参数传给decode_json,Perl子程序的参数列表默认是列表上下文)时,它会把文件按行分割,返回每行内容组成的列表。

此时decode_json只会接收列表的第一个元素(也就是JSON的第一行[),用这个不完整的片段解析JSON,自然会触发语法错误。

解决办法

有两种方式可以修复链式调用的问题:

  1. 强制标量上下文:用scalar关键字让read_file在标量上下文执行,返回完整字符串:
    my $chained_decoded = decode_json( scalar read_file('test.json') );
    
  2. 保留中间变量:也就是你最初正常运行的写法,通过赋值给标量变量触发标量上下文,这种方式也更直观易读。

内容的提问来源于stack exchange,提问作者awarrier99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:22:40