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

Ruby中Marshal::load方法的proc参数作用及使用示例咨询

Understanding the proc Argument in Marshal::load

Great question! It’s totally relatable that the official Ruby docs only give a brief description of this parameter without real-world examples. Let’s break down how this proc works and walk through practical use cases.

First, a quick recap of the official docs excerpt you shared:

load( source [, proc] ) → obj
将source中的序列化数据转换为Ruby对象(可能包含关联的从属对象)并返回结果。source可以是IO实例或响应to_str方法的对象。如果指定了proc参数,每个对象在反序列化过程中都会被传递给该proc。

In plain terms: the proc acts as a callback that runs for every single object (including nested child objects) as it’s deserialized from the source. You can use this to log, modify, validate, or transform objects during the load process.

Example 1: Logging Deserialized Objects

This is a simple use case to track exactly what’s being loaded, which can be helpful for debugging:

# First, serialize some nested data
serialized_data = Marshal.dump([{username: "jane_doe", posts: 15}, "welcome message", 2024])

# Create a proc to log each object's type and content
logging_proc = Proc.new do |obj|
  puts "[Deserialized] Type: #{obj.class} | Value: #{obj.inspect}"
end

# Load the data with the logging proc
result = Marshal.load(serialized_data, logging_proc)

When you run this, you’ll see output for every object in the nested structure:

[Deserialized] Type: Array | Value: [{:username=>"jane_doe", :posts=>15}, "welcome message", 2024]
[Deserialized] Type: Hash | Value: {:username=>"jane_doe", :posts=>15}
[Deserialized] Type: String | Value: "jane_doe"
[Deserialized] Type: Integer | Value: 15
[Deserialized] Type: String | Value: "welcome message"
[Deserialized] Type: Integer | Value: 2024

Example 2: Modifying Objects During Deserialization

You can use the proc to transform objects as they’re loaded—like updating old data formats or adding metadata:

# Serialize a list of product names
serialized_products = Marshal.dump(["Laptop", "Phone", ["Headphones", "Charger"]])

# A proc to add a timestamp suffix to all strings
modify_proc = Proc.new do |obj|
  obj << " (loaded at #{Time.now.strftime("%H:%M")})" if obj.is_a?(String)
end

# Load and modify the data
updated_products = Marshal.load(serialized_products, modify_proc)
puts updated_products.inspect

The output will show every string (including nested ones) modified:

["Laptop (loaded at 14:30)", "Phone (loaded at 14:30)", ["Headphones (loaded at 14:30)", "Charger (loaded at 14:30)"]]

Example 3: Validating Objects for Security/Integrity

If you’re loading serialized data from a semi-trusted source, you can use the proc to validate objects before they’re fully returned:

class Order
  attr_accessor :id, :total
  def initialize(id, total)
    @id = id
    @total = total
  end
end

# Serialize an order with an invalid negative total
serialized_order = Marshal.dump(Order.new(123, -50))

# A proc to validate order totals
validation_proc = Proc.new do |obj|
  if obj.is_a?(Order) && obj.total < 0
    raise ArgumentError, "Invalid order ##{obj.id}: Total cannot be negative!"
  end
end

# Attempt to load the invalid order
begin
  Marshal.load(serialized_order, validation_proc)
rescue ArgumentError => e
  puts e.message # Output: Invalid order #123: Total cannot be negative!
end

Key Notes

  • The proc runs for every object in the deserialization tree, including nested arrays, hashes, and custom class instances.
  • This is especially useful for data migration (updating old object structures to new ones) or adding extra safety checks (though remember: Marshal is not designed for untrusted data—this is just an extra layer).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 21:32:39