[ruby-trunk - Bug #5586][Open] Time.at(Marshal.load(Marshal.dump(Time.now))).to_s raise TypeError

Issue #5586 has been reported by Tomoyuki C…


Bug #5586: Time.at(Marshal.load(Marshal.dump(Time.now))).to_s raise
TypeError

Author: Tomoyuki C.
Status: Open
Priority: Normal
Assignee:
Category: core
Target version:
ruby -v: ruby 2.0.0dev (2011-11-07 trunk 33656) [x86_64-darwin10.8.0]

以下のコードが TypeError を発生させます。なお 1.9.2-p312 でも発生しました。

Time.at(Marshal.load(Marshal.dump(Time.now))).to_s

=> TypeError: false can’t be coerced into Fixnum

Time オブジェクトを Marshal.dump → load すると TIME_SET_FIXOFF() で
struct time_object の gmt と vtm.utc_offset がセットされるのですが
それを Time.at に渡すと gmt だけコピーされて vtm.utc_offset が (VALUE)0 = Qfalse
のままだからのようです。

どこが根本的な原因なのかよくわかりませんが、以下のパッチで例外はおきなくなりました。
るりまの Time.at(time) のページ(
http://rurema.clear-code.com/1.9.3/method/Time/s/at.html )を見ると
「生成された Time オブジェクトのタイムゾーンは地方時となります。」とあるので TIME_GMT_COPY() 自体が
不要なのかもしれないと思いますがどうでしょう。

diff --git a/time.c b/time.c
index 3e50c7c…96b717b 100644
— a/time.c
+++ b/time.c
@@ -1820,7 +1820,10 @@ struct time_object {
(tobj)->vtm.utc_offset = (off),
(tobj)->vtm.zone = NULL)

-#define TIME_COPY_GMT(tobj1, tobj2) ((tobj1)->gmt = (tobj2)->gmt)
+#define TIME_COPY_GMT(tobj1, tobj2) \

  • ((tobj1)->gmt = (tobj2)->gmt, \
  • (tobj1)->vtm.utc_offset = (tobj2)->vtm.utc_offset, \
    
  • (tobj1)->vtm.zone = (tobj2)->vtm.zone)
    

static VALUE time_get_tm(VALUE, struct time_object *);
#define MAKE_TM(time, tobj) \

2011$BG/(B11$B7n(B8$BF|(B0:42 Tomoyuki C.
[email protected]:

Time.at(Marshal.load(Marshal.dump(Time.now))).to_s

=> TypeError: false can’t be coerced into Fixnum

Time $B%*%V%8%'%/%H$r(B Marshal.dump → load $B$9$k$H(B TIME_SET_FIXOFF() $B$G(B
struct time_object $B$N(B gmt $B$H(B vtm.utc_offset $B$,%;%C%H$5$l$k$N$G$9$,(B
$B$=$l$r(B Time.at $B$KEO$9$H(B gmt $B$@$1%3%T!<$5$l$F(B vtm.utc_offset $B$,(B
(VALUE)0 = Qfalse $B$N$^$^$@$+$i$N$h$&$G$9!#(B

$B$I$3$,:,K\E*$J860x$J$N$+$h$/$o$+$j$^$;$s$,!"0J2<$N%Q%C%A$GNc30$O$*$-$J$/$J$j$^$7$?!#(B

$B%Q%C%A$rF~$l$^$7$?!#(B

$B$k$j$^$N(B Time.at(time) $B$N%Z!<%8(B(
http://rurema.clear-code.com/1.9.3/method/Time/s/at.html )$B$r8+$k$H(B
$B!V@8@.$5$l$?(B Time
$B%*%V%8%'%/%H$N%?%$%`%>!<%s$OCOJ};~$H$J$j$^$9!#!W$H$"$k$N$G(B TIME_GMT_COPY()
$B<+BN$,(B
$BITMW$J$N$+$b$7$l$J$$$H;W$$$^$9$,$I$&$G$7$g$&!#(B

time.c $BCf$N%I%-%e%a%s%H$K$O$=$&$$$&5-=R$O$“$j$^$;$s$M!#(B
$B!V@8@.$5$l$?(B Time
$B%*%V%8%'%/%H$N%?%$%`%>!<%s$OCOJ};~$H$J$j$^$9!#!W$H$$$&$N$O(B
$B<BBV$K$”$C$F$$$J$$$N$GC1$J$k%P%0$8$c$J$$$G$7$g$&$+!#(B

Issue #5586 has been updated by dafiku (dafi harisy).

Everlastingly, an issue with the intention of I am passionate in this
vicinity. I be inflicted with looked for in rank of this feature for the
last numerous hours. Your locate is greatly valued.
http://www.yourhousecontents.com/
http://www.electroscanogram.com/
http://www.videophototravel.info/
http://www.supershinelaundry.com/
http://www.ywor.info/
http://www.bicity.info/
http://www.ubidyne.info/

Backport #5586: Time.at(Marshal.load(Marshal.dump(Time.now))).to_s raise
TypeError

Author: nagachika (Tomoyuki C.)
Status: Closed
Priority: Normal
Assignee:
Category:
Target version:

以下のコードが TypeError を発生させます。なお 1.9.2-p312 でも発生しました。

Time.at(Marshal.load(Marshal.dump(Time.now))).to_s

=> TypeError: false can’t be coerced into Fixnum

Time オブジェクトを Marshal.dump → load すると TIME_SET_FIXOFF() で
struct time_object の gmt と vtm.utc_offset がセットされるのですが
それを Time.at に渡すと gmt だけコピーされて vtm.utc_offset が (VALUE)0 = Qfalse
のままだからのようです。

どこが根本的な原因なのかよくわかりませんが、以下のパッチで例外はおきなくなりました。
るりまの Time.at(time) のページ(
http://rurema.clear-code.com/1.9.3/method/Time/s/at.html )を見ると
「生成された Time オブジェクトのタイムゾーンは地方時となります。」とあるので TIME_GMT_COPY() 自体が
不要なのかもしれないと思いますがどうでしょう。

diff --git a/time.c b/time.c
index 3e50c7c…96b717b 100644
— a/time.c
+++ b/time.c
@@ -1820,7 +1820,10 @@ struct time_object {
(tobj)->vtm.utc_offset = (off),
(tobj)->vtm.zone = NULL)

-#define TIME_COPY_GMT(tobj1, tobj2) ((tobj1)->gmt = (tobj2)->gmt)
+#define TIME_COPY_GMT(tobj1, tobj2) \

  • ((tobj1)->gmt = (tobj2)->gmt, \
  • (tobj1)->vtm.utc_offset = (tobj2)->vtm.utc_offset, \
    
  • (tobj1)->vtm.zone = (tobj2)->vtm.zone)
    

static VALUE time_get_tm(VALUE, struct time_object *);
#define MAKE_TM(time, tobj) \