Module: Marshal

Defined in:
marshal.c

Constant Summary collapse

MAJOR_VERSION =

major version

INT2FIX(MARSHAL_MAJOR)
MINOR_VERSION =

minor version

INT2FIX(MARSHAL_MINOR)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.dump(obj[, anIO], limit = -1) ⇒ Object

Serializes obj and all descendant objects. If anIO is specified, the serialized data will be written to it, otherwise the data will be returned as a String. If limit is specified, the traversal of subobjects will be limited to that depth. If limit is negative, no checking of depth will be performed.

class Klass
  def initialize(str)
    @str = str
  end
  def say_hello
    @str
  end
end

(produces no output)

o = Klass.new("hello\n")
data = Marshal.dump(o)
obj = Marshal.load(data)
obj.say_hello  #=> "hello\n"

Marshal can’t dump following objects:

  • anonymous Class/Module.

  • objects which are related to system (ex: Dir, File::Stat, IO, File, Socket and so on)

  • an instance of MatchData, Data, Method, UnboundMethod, Proc, Thread, ThreadGroup, Continuation

  • objects which define singleton methods



980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
# File 'marshal.c', line 980

static VALUE
marshal_dump(int argc, VALUE *argv)
{
    VALUE obj, port, a1, a2;
    int limit = -1;
    struct dump_arg *arg;
    VALUE wrapper; /* used to avoid memory leak in case of exception */

    port = Qnil;
    rb_scan_args(argc, argv, "12", &obj, &a1, &a2);
    if (argc == 3) {
	if (!NIL_P(a2)) limit = NUM2INT(a2);
	if (NIL_P(a1)) io_needed();
	port = a1;
    }
    else if (argc == 2) {
	if (FIXNUM_P(a1)) limit = FIX2INT(a1);
	else if (NIL_P(a1)) io_needed();
	else port = a1;
    }
    wrapper = TypedData_Make_Struct(rb_cData, struct dump_arg, &dump_arg_data, arg);
    arg->dest = 0;
    arg->symbols = st_init_numtable();
    arg->data    = rb_init_identtable();
    arg->infection = 0;
    arg->compat_tbl = 0;
    arg->encodings = 0;
    arg->str = rb_str_buf_new(0);
    if (!NIL_P(port)) {
	if (!rb_respond_to(port, s_write)) {
	    io_needed();
	}
	arg->dest = port;
	if (rb_check_funcall(port, s_binmode, 0, 0) != Qundef) {
	    check_dump_arg(arg, s_binmode);
	}
    }
    else {
	port = arg->str;
    }

    w_byte(MARSHAL_MAJOR, arg);
    w_byte(MARSHAL_MINOR, arg);

    w_object(obj, arg, limit);
    if (arg->dest) {
	rb_io_write(arg->dest, arg->str);
	rb_str_resize(arg->str, 0);
    }
    clear_dump_arg(arg);
    RB_GC_GUARD(wrapper);

    return port;
}

.load(source[, proc]) ⇒ Object .restore(source[, proc]) ⇒ Object

Returns the result of converting the serialized data in source into a Ruby object (possibly with associated subordinate objects). source may be either an instance of IO or an object that responds to to_str. If proc is specified, each object will be passed to the proc, as the object is being deserialized.

Never pass untrusted data (including user supplied input) to this method. Please see the overview for further details.

Overloads:



1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
# File 'marshal.c', line 1995

static VALUE
marshal_load(int argc, VALUE *argv)
{
    VALUE port, proc;
    int major, minor, infection = 0;
    VALUE v;
    VALUE wrapper; /* used to avoid memory leak in case of exception */
    struct load_arg *arg;

    rb_scan_args(argc, argv, "11", &port, &proc);
    v = rb_check_string_type(port);
    if (!NIL_P(v)) {
	infection = (int)FL_TEST(port, MARSHAL_INFECTION); /* original taintedness */
	port = v;
    }
    else if (rb_respond_to(port, s_getbyte) && rb_respond_to(port, s_read)) {
	rb_check_funcall(port, s_binmode, 0, 0);
	infection = (int)FL_TAINT;
    }
    else {
	io_needed();
    }
    wrapper = TypedData_Make_Struct(rb_cData, struct load_arg, &load_arg_data, arg);
    arg->infection = infection;
    arg->src = port;
    arg->offset = 0;
    arg->symbols = st_init_numtable();
    arg->data    = rb_init_identtable();
    arg->compat_tbl = 0;
    arg->proc = 0;
    arg->readable = 0;

    if (NIL_P(v))
	arg->buf = xmalloc(BUFSIZ);
    else
	arg->buf = 0;

    major = r_byte(arg);
    minor = r_byte(arg);
    if (major != MARSHAL_MAJOR || minor > MARSHAL_MINOR) {
	clear_load_arg(arg);
	rb_raise(rb_eTypeError, "incompatible marshal file format (can't be read)\n\
\tformat version %d.%d required; %d.%d given",
		 MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
    }
    if (RTEST(ruby_verbose) && minor != MARSHAL_MINOR) {
	rb_warn("incompatible marshal file format (can be read)\n\
\tformat version %d.%d required; %d.%d given",
		MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
    }

    if (!NIL_P(proc)) arg->proc = proc;
    v = r_object(arg);
    clear_load_arg(arg);
    RB_GC_GUARD(wrapper);

    return v;
}

.load(source[, proc]) ⇒ Object .restore(source[, proc]) ⇒ Object

Returns the result of converting the serialized data in source into a Ruby object (possibly with associated subordinate objects). source may be either an instance of IO or an object that responds to to_str. If proc is specified, each object will be passed to the proc, as the object is being deserialized.

Never pass untrusted data (including user supplied input) to this method. Please see the overview for further details.

Overloads:



1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
# File 'marshal.c', line 1995

static VALUE
marshal_load(int argc, VALUE *argv)
{
    VALUE port, proc;
    int major, minor, infection = 0;
    VALUE v;
    VALUE wrapper; /* used to avoid memory leak in case of exception */
    struct load_arg *arg;

    rb_scan_args(argc, argv, "11", &port, &proc);
    v = rb_check_string_type(port);
    if (!NIL_P(v)) {
	infection = (int)FL_TEST(port, MARSHAL_INFECTION); /* original taintedness */
	port = v;
    }
    else if (rb_respond_to(port, s_getbyte) && rb_respond_to(port, s_read)) {
	rb_check_funcall(port, s_binmode, 0, 0);
	infection = (int)FL_TAINT;
    }
    else {
	io_needed();
    }
    wrapper = TypedData_Make_Struct(rb_cData, struct load_arg, &load_arg_data, arg);
    arg->infection = infection;
    arg->src = port;
    arg->offset = 0;
    arg->symbols = st_init_numtable();
    arg->data    = rb_init_identtable();
    arg->compat_tbl = 0;
    arg->proc = 0;
    arg->readable = 0;

    if (NIL_P(v))
	arg->buf = xmalloc(BUFSIZ);
    else
	arg->buf = 0;

    major = r_byte(arg);
    minor = r_byte(arg);
    if (major != MARSHAL_MAJOR || minor > MARSHAL_MINOR) {
	clear_load_arg(arg);
	rb_raise(rb_eTypeError, "incompatible marshal file format (can't be read)\n\
\tformat version %d.%d required; %d.%d given",
		 MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
    }
    if (RTEST(ruby_verbose) && minor != MARSHAL_MINOR) {
	rb_warn("incompatible marshal file format (can be read)\n\
\tformat version %d.%d required; %d.%d given",
		MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
    }

    if (!NIL_P(proc)) arg->proc = proc;
    v = r_object(arg);
    clear_load_arg(arg);
    RB_GC_GUARD(wrapper);

    return v;
}

Instance Method Details

#dump(obj[, anIO], limit = -1) ⇒ Object (private)

Serializes obj and all descendant objects. If anIO is specified, the serialized data will be written to it, otherwise the data will be returned as a String. If limit is specified, the traversal of subobjects will be limited to that depth. If limit is negative, no checking of depth will be performed.

class Klass
  def initialize(str)
    @str = str
  end
  def say_hello
    @str
  end
end

(produces no output)

o = Klass.new("hello\n")
data = Marshal.dump(o)
obj = Marshal.load(data)
obj.say_hello  #=> "hello\n"

Marshal can’t dump following objects:

  • anonymous Class/Module.

  • objects which are related to system (ex: Dir, File::Stat, IO, File, Socket and so on)

  • an instance of MatchData, Data, Method, UnboundMethod, Proc, Thread, ThreadGroup, Continuation

  • objects which define singleton methods



980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
# File 'marshal.c', line 980

static VALUE
marshal_dump(int argc, VALUE *argv)
{
    VALUE obj, port, a1, a2;
    int limit = -1;
    struct dump_arg *arg;
    VALUE wrapper; /* used to avoid memory leak in case of exception */

    port = Qnil;
    rb_scan_args(argc, argv, "12", &obj, &a1, &a2);
    if (argc == 3) {
	if (!NIL_P(a2)) limit = NUM2INT(a2);
	if (NIL_P(a1)) io_needed();
	port = a1;
    }
    else if (argc == 2) {
	if (FIXNUM_P(a1)) limit = FIX2INT(a1);
	else if (NIL_P(a1)) io_needed();
	else port = a1;
    }
    wrapper = TypedData_Make_Struct(rb_cData, struct dump_arg, &dump_arg_data, arg);
    arg->dest = 0;
    arg->symbols = st_init_numtable();
    arg->data    = rb_init_identtable();
    arg->infection = 0;
    arg->compat_tbl = 0;
    arg->encodings = 0;
    arg->str = rb_str_buf_new(0);
    if (!NIL_P(port)) {
	if (!rb_respond_to(port, s_write)) {
	    io_needed();
	}
	arg->dest = port;
	if (rb_check_funcall(port, s_binmode, 0, 0) != Qundef) {
	    check_dump_arg(arg, s_binmode);
	}
    }
    else {
	port = arg->str;
    }

    w_byte(MARSHAL_MAJOR, arg);
    w_byte(MARSHAL_MINOR, arg);

    w_object(obj, arg, limit);
    if (arg->dest) {
	rb_io_write(arg->dest, arg->str);
	rb_str_resize(arg->str, 0);
    }
    clear_dump_arg(arg);
    RB_GC_GUARD(wrapper);

    return port;
}

#load(source[, proc]) ⇒ Object (private) #restore(source[, proc]) ⇒ Object (private)

Returns the result of converting the serialized data in source into a Ruby object (possibly with associated subordinate objects). source may be either an instance of IO or an object that responds to to_str. If proc is specified, each object will be passed to the proc, as the object is being deserialized.

Never pass untrusted data (including user supplied input) to this method. Please see the overview for further details.

Overloads:



1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
# File 'marshal.c', line 1995

static VALUE
marshal_load(int argc, VALUE *argv)
{
    VALUE port, proc;
    int major, minor, infection = 0;
    VALUE v;
    VALUE wrapper; /* used to avoid memory leak in case of exception */
    struct load_arg *arg;

    rb_scan_args(argc, argv, "11", &port, &proc);
    v = rb_check_string_type(port);
    if (!NIL_P(v)) {
	infection = (int)FL_TEST(port, MARSHAL_INFECTION); /* original taintedness */
	port = v;
    }
    else if (rb_respond_to(port, s_getbyte) && rb_respond_to(port, s_read)) {
	rb_check_funcall(port, s_binmode, 0, 0);
	infection = (int)FL_TAINT;
    }
    else {
	io_needed();
    }
    wrapper = TypedData_Make_Struct(rb_cData, struct load_arg, &load_arg_data, arg);
    arg->infection = infection;
    arg->src = port;
    arg->offset = 0;
    arg->symbols = st_init_numtable();
    arg->data    = rb_init_identtable();
    arg->compat_tbl = 0;
    arg->proc = 0;
    arg->readable = 0;

    if (NIL_P(v))
	arg->buf = xmalloc(BUFSIZ);
    else
	arg->buf = 0;

    major = r_byte(arg);
    minor = r_byte(arg);
    if (major != MARSHAL_MAJOR || minor > MARSHAL_MINOR) {
	clear_load_arg(arg);
	rb_raise(rb_eTypeError, "incompatible marshal file format (can't be read)\n\
\tformat version %d.%d required; %d.%d given",
		 MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
    }
    if (RTEST(ruby_verbose) && minor != MARSHAL_MINOR) {
	rb_warn("incompatible marshal file format (can be read)\n\
\tformat version %d.%d required; %d.%d given",
		MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
    }

    if (!NIL_P(proc)) arg->proc = proc;
    v = r_object(arg);
    clear_load_arg(arg);
    RB_GC_GUARD(wrapper);

    return v;
}

#load(source[, proc]) ⇒ Object (private) #restore(source[, proc]) ⇒ Object (private)

Returns the result of converting the serialized data in source into a Ruby object (possibly with associated subordinate objects). source may be either an instance of IO or an object that responds to to_str. If proc is specified, each object will be passed to the proc, as the object is being deserialized.

Never pass untrusted data (including user supplied input) to this method. Please see the overview for further details.

Overloads:



1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
# File 'marshal.c', line 1995

static VALUE
marshal_load(int argc, VALUE *argv)
{
    VALUE port, proc;
    int major, minor, infection = 0;
    VALUE v;
    VALUE wrapper; /* used to avoid memory leak in case of exception */
    struct load_arg *arg;

    rb_scan_args(argc, argv, "11", &port, &proc);
    v = rb_check_string_type(port);
    if (!NIL_P(v)) {
	infection = (int)FL_TEST(port, MARSHAL_INFECTION); /* original taintedness */
	port = v;
    }
    else if (rb_respond_to(port, s_getbyte) && rb_respond_to(port, s_read)) {
	rb_check_funcall(port, s_binmode, 0, 0);
	infection = (int)FL_TAINT;
    }
    else {
	io_needed();
    }
    wrapper = TypedData_Make_Struct(rb_cData, struct load_arg, &load_arg_data, arg);
    arg->infection = infection;
    arg->src = port;
    arg->offset = 0;
    arg->symbols = st_init_numtable();
    arg->data    = rb_init_identtable();
    arg->compat_tbl = 0;
    arg->proc = 0;
    arg->readable = 0;

    if (NIL_P(v))
	arg->buf = xmalloc(BUFSIZ);
    else
	arg->buf = 0;

    major = r_byte(arg);
    minor = r_byte(arg);
    if (major != MARSHAL_MAJOR || minor > MARSHAL_MINOR) {
	clear_load_arg(arg);
	rb_raise(rb_eTypeError, "incompatible marshal file format (can't be read)\n\
\tformat version %d.%d required; %d.%d given",
		 MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
    }
    if (RTEST(ruby_verbose) && minor != MARSHAL_MINOR) {
	rb_warn("incompatible marshal file format (can be read)\n\
\tformat version %d.%d required; %d.%d given",
		MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
    }

    if (!NIL_P(proc)) arg->proc = proc;
    v = r_object(arg);
    clear_load_arg(arg);
    RB_GC_GUARD(wrapper);

    return v;
}