Module: Marshal

Defined in:
marshal.c

Constant Summary collapse

MAJOR_VERSION =
INT2FIX(MARSHAL_MAJOR)
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 related to its system (ex: Dir, File::Stat, IO, File, Socket and so on)

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

  • objects which defines singleton methods


917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
# File 'marshal.c', line 917

static VALUE
marshal_dump(int argc, VALUE *argv)
{
    VALUE obj, port, a1, a2;
    int limit = -1;
    struct dump_arg *arg;
    VALUE wrapper;

    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;
    }
    RB_GC_GUARD(wrapper) = TypedData_Make_Struct(rb_cData, struct dump_arg, &dump_arg_data, arg);
    arg->dest = 0;
    arg->symbols = st_init_numtable();
    arg->data    = st_init_numtable();
    arg->infection = 0;
    arg->compat_tbl = st_init_numtable();
    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, it will be passed each object as it is deserialized.

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

Overloads:


1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
# File 'marshal.c', line 1901

static VALUE
marshal_load(int argc, VALUE *argv)
{
    VALUE port, proc;
    int major, minor, infection = 0;
    VALUE v;
    VALUE wrapper;
    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 | FL_TEST(port, FL_UNTRUSTED));
    }
    else {
	io_needed();
    }
    RB_GC_GUARD(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    = st_init_numtable();
    arg->compat_tbl = st_init_numtable();
    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, it will be passed each object as it is deserialized.

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

Overloads:


1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
# File 'marshal.c', line 1901

static VALUE
marshal_load(int argc, VALUE *argv)
{
    VALUE port, proc;
    int major, minor, infection = 0;
    VALUE v;
    VALUE wrapper;
    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 | FL_TEST(port, FL_UNTRUSTED));
    }
    else {
	io_needed();
    }
    RB_GC_GUARD(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    = st_init_numtable();
    arg->compat_tbl = st_init_numtable();
    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 related to its system (ex: Dir, File::Stat, IO, File, Socket and so on)

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

  • objects which defines singleton methods


917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
# File 'marshal.c', line 917

static VALUE
marshal_dump(int argc, VALUE *argv)
{
    VALUE obj, port, a1, a2;
    int limit = -1;
    struct dump_arg *arg;
    VALUE wrapper;

    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;
    }
    RB_GC_GUARD(wrapper) = TypedData_Make_Struct(rb_cData, struct dump_arg, &dump_arg_data, arg);
    arg->dest = 0;
    arg->symbols = st_init_numtable();
    arg->data    = st_init_numtable();
    arg->infection = 0;
    arg->compat_tbl = st_init_numtable();
    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, it will be passed each object as it is deserialized.

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

Returns:


1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
# File 'marshal.c', line 1901

static VALUE
marshal_load(int argc, VALUE *argv)
{
    VALUE port, proc;
    int major, minor, infection = 0;
    VALUE v;
    VALUE wrapper;
    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 | FL_TEST(port, FL_UNTRUSTED));
    }
    else {
	io_needed();
    }
    RB_GC_GUARD(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    = st_init_numtable();
    arg->compat_tbl = st_init_numtable();
    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, it will be passed each object as it is deserialized.

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

Returns:


1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
# File 'marshal.c', line 1901

static VALUE
marshal_load(int argc, VALUE *argv)
{
    VALUE port, proc;
    int major, minor, infection = 0;
    VALUE v;
    VALUE wrapper;
    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 | FL_TEST(port, FL_UNTRUSTED));
    }
    else {
	io_needed();
    }
    RB_GC_GUARD(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    = st_init_numtable();
    arg->compat_tbl = st_init_numtable();
    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;
}