[#14696] Inconsistency in rescuability of "return" — Charles Oliver Nutter <charles.nutter@...>

Why can you not rescue return, break, etc when they are within

21 messages 2008/01/02
[#14699] Re: Inconsistency in rescuability of "return" — Gary Wright <gwtmp01@...> 2008/01/02

[#14738] Enumerable#zip Needs Love — James Gray <james@...>

The community has been building a Ruby 1.9 compatibility tip list on

15 messages 2008/01/03
[#14755] Re: Enumerable#zip Needs Love — Martin Duerst <duerst@...> 2008/01/04

Hello James,

[#14772] Manual Memory Management — Pramukta Kumar <prak@...>

I was thinking it would be nice to be able to free large objects at

36 messages 2008/01/04
[#14788] Re: Manual Memory Management — Marcin Raczkowski <mailing.mr@...> 2008/01/05

I would only like to add that RMgick for example provides free method to

[#14824] Re: Manual Memory Management — MenTaLguY <mental@...> 2008/01/07

On Sat, 5 Jan 2008 15:49:30 +0900, Marcin Raczkowski <mailing.mr@gmail.com> wrote:

[#14825] Re: Manual Memory Management — "Evan Weaver" <evan@...> 2008/01/07

Python supports 'del reference', which decrements the reference

[#14838] Re: Manual Memory Management — Marcin Raczkowski <mailing.mr@...> 2008/01/08

Evan Weaver wrote:

[#14911] Draft of some pages about encoding in Ruby 1.9 — Dave Thomas <dave@...>

Folks:

24 messages 2008/01/10

[#14976] nil encoding as synonym for binary encoding — David Flanagan <david@...>

The following just appeared in the ChangeLog

37 messages 2008/01/11
[#14977] Re: nil encoding as synonym for binary encoding — Yukihiro Matsumoto <matz@...> 2008/01/11

Hi,

[#14978] Re: nil encoding as synonym for binary encoding — Dave Thomas <dave@...> 2008/01/11

[#14979] Re: nil encoding as synonym for binary encoding — David Flanagan <david@...> 2008/01/11

Dave Thomas wrote:

[#14993] Re: nil encoding as synonym for binary encoding — Dave Thomas <dave@...> 2008/01/11

[#14980] Re: nil encoding as synonym for binary encoding — Gary Wright <gwtmp01@...> 2008/01/11

[#14981] Re: nil encoding as synonym for binary encoding — Yukihiro Matsumoto <matz@...> 2008/01/11

Hi,

[#14995] Re: nil encoding as synonym for binary encoding — David Flanagan <david@...> 2008/01/11

Yukihiro Matsumoto writes:

[#15050] how to "borrow" the RDoc::RubyParser and HTMLGenerator — Phlip <phlip2005@...>

Core Rubies:

17 messages 2008/01/13
[#15060] Re: how to "borrow" the RDoc::RubyParser and HTMLGenerator — Eric Hodel <drbrain@...7.net> 2008/01/14

On Jan 13, 2008, at 08:54 AM, Phlip wrote:

[#15062] Re: how to "borrow" the RDoc::RubyParser and HTMLGenerator — Phlip <phlip2005@...> 2008/01/14

Eric Hodel wrote:

[#15073] Re: how to "borrow" the RDoc::RubyParser and HTMLGenerator — Eric Hodel <drbrain@...7.net> 2008/01/14

On Jan 13, 2008, at 20:35 PM, Phlip wrote:

[#15185] Friendlier methods to compare two Time objects — "Jim Cropcho" <jim.cropcho@...>

Hello,

10 messages 2008/01/22

[#15194] Can large scale projects be successful implemented around a dynamic programming language? — Jordi <mumismo@...>

A good article I have found (may have been linked by slashdot, don't know)

8 messages 2008/01/24

[#15248] Symbol#empty? ? — "David A. Black" <dblack@...>

Hi --

24 messages 2008/01/28
[#15250] Re: Symbol#empty? ? — Yukihiro Matsumoto <matz@...> 2008/01/28

Hi,

Re: [PATCH] Friendlier methods to compare two Time objects

From: "Jim Cropcho" <jim.cropcho@...>
Date: 2008-01-25 01:28:52 UTC
List: ruby-core #15207
Here is the newest patch. It creates a module called Temporal which contains
functionality useful to classes which define temporal objects, such as dates
and times. However, its intended scope is *not* limited to object
comparison. It is handy in this regard, though, because it addresses
differences between languages, as several in this thread have noted.

The module is added to the compilation configuration, and unit tests are
included, all of which pass. The module is included in the classes Time and
Date (and DateTime, via extension).

The module does not include the methods past? and present?, as intended,
because the means of determining "now" is different even at the conceptual
level between temporal classes. For example, "now" to Time is the number of
microseconds after epoch, but "now" to Date is the current calendar date. It
is my opinion that past?/future? functionality should be implemented at the
class level.

Please give my concept and source code consideration for being entered into
the ruby core, and suggest modifications/additions at will.


Jim Cropcho

2008/1/23 Jim Cropcho <jim.cropcho@gmail.com>:

> A new thought:
>
> > The way that the <=> method is rewritten for Time, it is
> > optimized (as far as I can tell) to evaluate conditions
> > based on nanoseconds only when equality cannot be
> > determined via seconds. I may be misreading that.
> >
> > Conversely, Time inherits its > and < methods from its superclass,
> > so surely those optimizations in <=> do not exist, and creating
> > aliases would yield less-optimized code. Also, in the other classes
> > where I add this functionality, current techniques to optimize
> > comparisons will be reimplemented using the local methodology.
>
> from the rdoc for compar.c:
>
> The Comparable <http://ruby-doc.org/core/classes/Comparable.html> mixin is
> used by classes whose objects may be ordered. The class must define the
> <=> operator, which compares the receiver against another object,
> returning -1, 0, or +1 depending on whether the receiver is less than, equal
> to, or greater than the other object. Comparable<http://ruby-doc.org/core/classes/Comparable.html>uses
> <=> to implement the conventional comparison operators (<, <=, ==, >=, and
> >) and the method between?<http://ruby-doc.org/core/classes/Comparable.html#M007548>
> .
>
> I am now writing a Mixin called Temporal which will be included in the
> Time , Date and DateTime classes, and will contain the instance methods
>
> *before?(some_time)
> *after?(some_time)
> *future?(time = Time.now)
> *past?(time = Time.now)
>
> I have the tests written and skeleton code to compile and include the
> module where necessary. I hope to be finished tomorrow.
>
> 2008/1/23 Mathieu Blondel < mblondel@rubyforge.org >:
>
> > Hi,
> >
> > 2008/1/23, Martin Duerst < duerst@it.aoyama.ac.jp>:
> >
> > > There is even some cultural dependency here. In Japanese, for example,
> > > the past is higher than the future, time flows down,
> >
> > And in Chinese as well. For example:
> >
> > 下个星期 = next week, lit. below week
> > 上个星期 = last week, lit. above week
> >
> >
> > Mathieu
> >
> >
>

Attachments (1)

ruby-module_temporal.patch (7.65 KB, text/x-diff)
Index: time.c
===================================================================
--- time.c	(revision 15221)
+++ time.c	(working copy)
@@ -2332,6 +2332,7 @@
 
     rb_cTime = rb_define_class("Time", rb_cObject);
     rb_include_module(rb_cTime, rb_mComparable);
+    rb_include_module(rb_cTime, rb_mTemporal);
 
     rb_define_alloc_func(rb_cTime, time_s_alloc);
     rb_define_singleton_method(rb_cTime, "now", rb_class_new_instance, -1);
Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h	(revision 15221)
+++ include/ruby/intern.h	(working copy)
@@ -567,6 +567,8 @@
 VALUE rb_barrier_new(void);
 VALUE rb_barrier_wait(VALUE self);
 VALUE rb_barrier_release(VALUE self);
+/* temporal.c */
+int rb_temporalint(VALUE, VALUE, VALUE);
 /* time.c */
 VALUE rb_time_new(time_t, long);
 VALUE rb_time_nano_new(time_t, long);
Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 15221)
+++ include/ruby/ruby.h	(working copy)
@@ -817,6 +817,7 @@
 RUBY_EXTERN VALUE rb_mGC;
 RUBY_EXTERN VALUE rb_mMath;
 RUBY_EXTERN VALUE rb_mProcess;
+RUBY_EXTERN VALUE rb_mTemporal;
 
 RUBY_EXTERN VALUE rb_cBasicObject;
 RUBY_EXTERN VALUE rb_cObject;
Index: temporal.c
===================================================================
--- temporal.c	(revision 0)
+++ temporal.c	(revision 0)
@@ -0,0 +1,103 @@
+/**********************************************************************
+
+  temporal.c -
+
+  $Author: akr $
+  created at: Wed 23 Jan 2008
+
+  code and documentation by Jim Cropcho <jim.cropcho@gmail.com>, 
+  with sections adapted from <compar.c>
+
+**********************************************************************/
+
+#include "ruby/ruby.h"
+
+VALUE rb_mTemporal;
+
+static ID spaceship;
+
+int
+rb_temporalint(VALUE val, VALUE a, VALUE b)
+{
+    if (NIL_P(val)) {
+	rb_temporalerr(a, b);
+    }
+    if (FIXNUM_P(val)) return FIX2INT(val);
+    if (TYPE(val) == T_BIGNUM) {
+	if (RBIGNUM_SIGN(val)) return 1;
+	return -1;
+    }
+    if (RTEST(rb_funcall(val, '>', 1, INT2FIX(0)))) return 1;
+    if (RTEST(rb_funcall(val, '<', 1, INT2FIX(0)))) return -1;
+    return 0;
+}
+
+void
+rb_temporalerr(VALUE x, VALUE y)
+{
+    const char *classname;
+
+    if (SPECIAL_CONST_P(y)) {
+	y = rb_inspect(y);
+	classname = StringValuePtr(y);
+    }
+    else {
+	classname = rb_obj_classname(y);
+    }
+    rb_raise(rb_eArgError, "comparison of %s with %s failed",
+	     rb_obj_classname(x), classname);
+}
+
+/*
+ * call-seq:
+ *  obj.before?(other)
+ *
+ * Return <code>true</code> if <i>time</i> is before <i>other_time</i>, or
+ * <code>false</code> if after or the same time as <i>other_time</i>.
+ */
+
+static VALUE
+temporal_before_p(VALUE x, VALUE y)
+{
+    VALUE c = rb_funcall(x, spaceship, 1, y);
+
+    if (rb_temporalint(c, x, y) < 0) return Qtrue;
+    return Qfalse;
+}
+
+/*
+ * call-seq:
+ *  obj.after?(other)
+ *
+ * Return <code>true</code> if <i>time</i> is after <i>other_time</i>, or
+ * <code>false</code> if before or the same time as <i>other_time</i>
+ */
+
+static VALUE
+temporal_after_p(VALUE x, VALUE y)
+{
+    VALUE c = rb_funcall(x, spaceship, 1, y);
+
+    if (rb_temporalint(c, x, y) > 0) return Qtrue;
+    return Qfalse;
+}
+
+/*
+ *  The <code>Temporal</code> mixin contains functionality useful to classes
+ *  which define temporal objects, such as dates and times. As with the <code>Comparable</code
+ *  mixin, the class must define the <code><=></code> operator. <code>Temporal</code>
+ *  uses <code><=></code> to implement the comparison operators <code>before?</code> 
+ *  and <code>after?</code>, although its intended scope is not limited to object comparison.
+ *     
+ *     earlier_temporal_object.before? later_temporal_object   # => true
+ *     earlier_temporal_object.after?    later_temporal_object   # => false
+ */
+
+void
+Init_Temporal(void)
+{
+    rb_mTemporal = rb_define_module("Temporal");
+		rb_define_method(rb_mTemporal, "before?", temporal_before_p, 1);
+		rb_define_method(rb_mTemporal, "after?", temporal_after_p, 1);
+    spaceship = rb_intern("<=>");
+}
Index: lib/date.rb
===================================================================
--- lib/date.rb	(revision 15221)
+++ lib/date.rb	(working copy)
@@ -226,10 +226,13 @@
 #
 # The Date class includes the Comparable module, allowing
 # date objects to be compared and sorted, ranges of dates
-# to be created, and so forth.
+# to be created, and so forth. The Temporal object is also
+# included to allow date objects to be compared using more
+# natural language.
 class Date
 
   include Comparable
+	include Temporal
 
   # Full month names, in English.  Months count from 1 to 12; a
   # month's numerical representation indexed into this array
Index: common.mk
===================================================================
--- common.mk	(revision 15221)
+++ common.mk	(working copy)
@@ -58,6 +58,7 @@
 		st.$(OBJEXT) \
 		string.$(OBJEXT) \
 		struct.$(OBJEXT) \
+		temporal.$(OBJEXT) \
 		time.$(OBJEXT) \
 		transcode.$(OBJEXT) \
 		util.$(OBJEXT) \
@@ -571,6 +572,9 @@
 struct.$(OBJEXT): {$(VPATH)}struct.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
   {$(VPATH)}defines.h {$(VPATH)}missing.h {$(VPATH)}intern.h \
   {$(VPATH)}st.h
+temporal.$(OBJEXT): {$(VPATH)}temporal.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
+  {$(VPATH)}defines.h {$(VPATH)}missing.h {$(VPATH)}intern.h \
+  {$(VPATH)}st.h
 thread.$(OBJEXT): {$(VPATH)}thread.c {$(VPATH)}eval_intern.h \
   {$(VPATH)}ruby.h {$(VPATH)}config.h {$(VPATH)}defines.h \
   {$(VPATH)}missing.h {$(VPATH)}intern.h {$(VPATH)}st.h {$(VPATH)}node.h \
Index: inits.c
===================================================================
--- inits.c	(revision 15221)
+++ inits.c	(working copy)
@@ -43,6 +43,7 @@
 void Init_signal(void);
 void Init_String(void);
 void Init_Struct(void);
+void Init_Temporal(void);
 void Init_Time(void);
 void Init_var_tables(void);
 void Init_version(void);
@@ -82,6 +83,7 @@
     Init_Range();
     Init_IO();
     Init_Dir();
+		Init_Temporal();
     Init_Time();
     Init_Random();
     Init_signal();
Index: test/ruby/test_temporal.rb
===================================================================
--- test/ruby/test_temporal.rb	(revision 0)
+++ test/ruby/test_temporal.rb	(revision 0)
@@ -0,0 +1,66 @@
+require 'test/unit'
+require 'date'
+
+class TimeClassExtensionsTest < Test::Unit::TestCase
+	
+	def test_before
+		old_time = Time.now - 1000
+		less_old_time = Time.now - 15
+		assert old_time.before?(less_old_time)
+	end
+	
+	def test_after
+		future_time = Time.now + 2
+		distant_future = Time.now + 20_000
+		assert distant_future.after?(future_time)
+	end
+	
+	def test_equal
+		time1 = Time.now
+		time2 = time1.clone
+		assert !time1.before?(time2)
+		assert !time1.after?(time2)
+	end
+end
+
+class DateClassExtensionsTest < Test::Unit::TestCase
+	def test_before
+		old_time = Date.today - 1000
+		less_old_time = Date.today - 15
+		assert old_time.before?(less_old_time)
+	end
+	
+	def test_after
+		future_time = Date.today + 2
+		distant_future = Date.today + 20000
+		assert distant_future.after?(future_time)
+	end
+	
+	def test_equal
+		time1 = Date.today
+		time2 = time1.clone
+		assert !time1.before?(time2)
+		assert !time1.after?(time2)
+	end
+end
+
+class DateTimeClassExtensionsTest < Test::Unit::TestCase
+	def test_before
+		old_time = DateTime.now - 1000
+		less_old_time = DateTime.now - 15
+		assert old_time.before?(less_old_time)
+	end
+	
+	def test_after
+		future_time = DateTime.now + 2
+		distant_future = DateTime.now + 20000
+		assert distant_future.after?(future_time)
+	end
+	
+	def test_equal
+		time1 = DateTime.now
+		time2 = time1.clone
+		assert !time1.before?(time2)
+		assert !time1.after?(time2)
+	end
+end

In This Thread