[#10467] Module re-inclusion in 1.9 vs 1.8 — "Rick DeNatale" <rick.denatale@...>
Some months ago I noticed that the semantics of module inclusion had
[#10468] Floats that are NaN have strange behavior — Jonas Kongslund <jonas@...>
Hi
[#10478] Plan to add ext/digest/lib/digest/hmac.rb to 1.8.6 or 1.8.7? — "Zev Blut" <rubyzbibd@...>
Hello,
[#10480] Ruby 1.8.6 delayed for seven days — "Akinori MUSHA" <knu@...>
I am afraid I have to announce that Ruby 1.8.6 final release will be
[#10490] Join with block — "Farrel Lifson" <farrel.lifson@...>
This patch adds the ability to give the Array#join method a block like so
[#10492] Ruby 1.8.6 preview3 has been released — "Akinori MUSHA" <knu@...>
Hi,
Akinori MUSHA wrote:
On Mon, 5 Mar 2007, Akinori MUSHA wrote:
On Mar 5, 2007, at 04:16, Hugh Sasse wrote:
On Tue, 6 Mar 2007, Eric Hodel wrote:
On Mar 5, 2007, at 10:46, Hugh Sasse wrote:
On Tue, 6 Mar 2007, Eric Hodel wrote:
On Mar 5, 2007, at 12:07, Hugh Sasse wrote:
On Tue, 6 Mar 2007, Eric Hodel wrote:
Hi,
On Tue, 6 Mar 2007, Nobuyoshi Nakada wrote:
Hi,
[#10494] make check for 1.8.6-preview3: TestDBM: DBMError: dbm_store failed — <noreply@...>
Bugs item #9031, was opened at 2007-03-04 12:57
[#10507] Dynamic Array#join with block — <noreply@...>
Patches item #9055, was opened at 2007-03-05 19:57
Hi,
On 06/03/07, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:
On 06/03/07, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:
Hi,
On 09/03/07, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:
[#10536] DRb freezes YARV? — "Meinrad Recheis" <meinrad.recheis@...>
dear all,
[#10552] ruby 1.8.5p12: default IO object for gets() ? — Unknown <borg@...3.net>
Hello..
[#10563] Ruby 1.8.6 has been released — "Akinori MUSHA" <knu@...>
Hello,
[#10575] 'rescue' with non-exception class — Brian Candler <B.Candler@...>
I was just caught out by this odd behaviour: a 'rescue' clause doesn't
[#10580] Kernel#exec on OSX — "Kent Sibilev" <ksruby@...>
Does anyone know how to explain this:
[#10585] Bugfix: Extension Compile Error with 1.8.6 — Lothar Scholz <mailinglists@...>
Hello,
[#10594] grave bug in 1.8.6's thread implementation — Sylvain Joyeux <sylvain.joyeux@...4x.org>
In ext/thread/thread.c, remove_one leaves the list in an inconsistent state.
On Thu, 15 Mar 2007 00:15:57 +0900, Sylvain Joyeux <sylvain.joyeux@m4x.org> wrote:
> > The fix is in thread-mutex-remove_one.diff.
On Thu, 15 Mar 2007 01:19:04 +0900, Sylvain Joyeux <sylvain.joyeux@m4x.org> wrote:
On Wednesday 14 March 2007 17:29, MenTaLguY wrote:
On Thu, 15 Mar 2007 01:48:42 +0900, Sylvain Joyeux <sylvain.joyeux@m4x.org> wrote:
Here the next one (hopefully the last)
On Thu, 15 Mar 2007 03:11:41 +0900, Sylvain Joyeux <sylvain.joyeux@m4x.org> wrote:
On Wednesday 14 March 2007, MenTaLguY wrote:
On Thu, 15 Mar 2007 06:07:30 +0900, Sylvain Joyeux <sylvain.joyeux@m4x.org> wrote:
At Thu, 15 Mar 2007 10:18:19 +0900,
> Which set of patches do you think should be committed? The former to
[#10615] Multiton in standard library — TRANS <transfire@...>
Hi--
On 3/15/07, Tom Pollard <tomp@earthlink.net> wrote:
On Mar 15, 2007, at 11:46 PM, TRANS wrote:
On 3/16/07, James Edward Gray II <james@grayproductions.net> wrote:
[#10646] Marshal.dump shouldn't complain about singletons if the _dump method is defined — <noreply@...>
Bugs item #9376, was opened at 2007-03-19 15:58
noreply@rubyforge.org wrote:
On Monday 19 March 2007 18:01, Urabe Shyouhei wrote:
Hi,
On 3/19/07, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:
Hi,
> |But what if that singleton class just contained a method that allowed
Hi,
[#10701] Discrepancy between GetoptLong.new and documentation — <noreply@...>
Bugs item #8384, was opened at 2007-02-02 10:06
> -----Original Message-----
[#10705] Google Summer of Code proposal. — "Pedro Del Gallego" <pedro.delgallego@...>
Hi,
On 3/21/07, Pedro Del Gallego <pedro.delgallego@gmail.com> wrote:
[#10711] Re: Extensions to ipaddr.rb — Brian Candler <B.Candler@...>
> Is this your intention?
[#10712] Ruby Method Signatures (was Re: Multiton in standard library) — "Rick DeNatale" <rick.denatale@...>
On 3/19/07, TRANS <transfire@gmail.com> wrote:
On 3/19/07, TRANS <transfire@gmail.com> wrote:
On 3/21/07, Jos Backus <jos@catnook.com> wrote:
On 3/21/07, TRANS <transfire@gmail.com> wrote:
On Thu, Mar 22, 2007 at 10:26:38PM +0900, Rick DeNatale wrote:
On 3/22/07, Paul Brannan <pbrannan@atdesk.com> wrote:
On 3/23/07, Rick DeNatale <rick.denatale@gmail.com> wrote:
[#10729] BUGS in metaclasses inheritance — <noreply@...>
Bugs item #9462, was opened at 22/03/2007 11:19
noreply@rubyforge.org wrote:
[#10746] sub-process with Test::Unit does not exit error code as expected — <noreply@...>
Bugs item #9300, was opened at 2007-03-15 03:35
Hi,
[#10749] class_extension — TRANS <transfire@...>
I'm just following up to find out the status of consideration for
[#10768] Lastest Version IRHG - Technical Review Requested — Charles Thornton <ceo@...>
TO: CORE
[#10798] Virtual classes and 'real' classes -- why? — "John Lam (CLR)" <jflam@...>
I was wondering if someone could help me understand why there's a parallel =
On Thu, 29 Mar 2007 04:44:16 +0900, "John Lam (CLR)" <jflam@microsoft.com> wrote:
Thanks for sharing the eigenclass hack.
John Lam (CLR) wrote:
[#10818] Bug in Net::HTTP#keep_alive? — Aaron Patterson <aaron@...>
Sometimes Apache will send a connection header like this:
Should I submit a bug for this? I guess I'm not sure what proper
[#10826] Comparable module and values of <=> operator — David Flanagan <david@...>
The rdoc for the Comparable module and its methods consistently indicate
Replying to my own post...
I think there's nothing wrong with the implementation and documentation.
Multiton in standard library
Hi--
I would like to propose that the Multiton pattern be supported in
Ruby's standard library. I believe the Multiton module originally
developed by Ara T. Howard and improved by myself is pretty solid at
this point. So I would like to offer it for the purpose.
The code follows for others to consider. And please let me know if you
have any suggestions for improving it further.
Thanks,
Trans
---
# = Multiton
#
# Multiton module that ensures only one object to be allocated for a given
# argument list.
#
# The 'multiton' pattern is similar to a singleton, but instead of only one
# instance, there are several similar instances. It is useful when you want to
# avoid constructing objects many times because of some huge expense (connecting
# to a database for example), require a set of similar but not identical
# objects, and cannot easily control how many times a contructor may be called.
#
# == Synopsis
#
# class SomeMultitonClass
# include Multiton
# attr :arg
# def initialize(arg)
# @arg = arg
# end
# end
#
# a = SomeMultitonClass.new(4)
# b = SomeMultitonClass.new(4) # a and b are same object
# c = SomeMultitonClass.new(2) # c is a different object
#
# == Previous Behavior
#
# In previous versions of Multiton the #new method was made
# private and #instance was used in its stay --just like Singleton.
# But this has proved less desirable for Multiton since Multitions can
# have multiple instances, not just one.
#
# So instead Multiton now defines #create as a private alias of
# the original #new method (just in case it is needed) and then
# defines #new to handle the multiton, and #instance is provided
# as an alias for it.
#
# == How It Works
#
# A pool of objects is searched for a previously cached object,
# if one is not found we construct one and cache it in the pool
# based on class and the args given to the contructor. To ensure
# equvalence, arguments are round-tripeed through Marshal. So
# only objects that can be marshalled can serve as arguments for
# the cache.
#
# Another limitation is that it is impossible to detect if different
# blocks were given to a contructor (if it takes a block). So it
# is the constructor arguments _only_ which determine the uniqueness
# of an object. To workaround this, define the _class_ method
# ::multiton_id.
#
# def Klass.multiton_id(*args, &block)
# # ...
# end
#
# Which should return a hash key used to identify the object being
# constructed as (not) unique.
module Multiton
# Pools of objects cached on class type.
POOLS = {}
# Method which can be defined by a class to determine object uniqueness.
MULTITON_ID_HOOK = :multiton_id
# Method which can be defined by a class to create multiton objects.
MULTITON_NEW_HOOK = :multiton_new
def self.append_features( klass )
class << klass
unless method_defined?(MULTITON_NEW_HOOK)
alias_method MULTITON_NEW_HOOK, :new
end
# Define #instance method. This will become #new.
def instance(*args, &block)
# if the class defined 'multiton_id' we use this as the key
# otherwise we simply use the argument list
k = begin
send MULTITON_ID_HOOK, *args, &block
rescue NameError
args
end
# marshal the args to serve as cache key (b/c hashes fail as this)
k = begin
Marshal.dump(k)
rescue TypeError
k
end
# Return cached object. Set if first occurance.
unless obj = (POOLS[self] ||= {})[k]
begin
critical = Thread.critical
Thread.critical = true
obj = (POOLS[self][k] = send(MULTITON_NEW_HOOK, *args, &block))
ensure
Thread.critical = critical # restore state
end
end
return obj
end
alias_method :create, :new
alias_method :new, :instance
end
end
## DON'T NEED THANKS TO MARSHAL
# Recursive dehash function. This converts hash into associative
# arrays, and any hashes that contains, etc.
#def self.dehash(arg)
# case arg
# when Hash
# arg.to_a.collect{|a| dehash(a)}
# when Array
# arg.collect{|a| dehash(a)}
# else
# arg
# end
#end
end
# _____ _
# |_ _|__ ___| |_
# | |/ _ \/ __| __|
# | | __/\__ \ |_
# |_|\___||___/\__|
#
=begin test
require 'test/unit'
#
# EXAMPLE A - STANDARD USAGE
#
class TC_Multiton_A < Test::Unit::TestCase
class SomeMultitonClass
include Multiton
attr :arg
def initialize(arg)
@arg = arg
end
end
def test_standard
a = SomeMultitonClass.instance(4)
b = SomeMultitonClass.instance(4) # a and b are same object
c = SomeMultitonClass.instance(2) # c is a different object
assert_equal( a, b )
assert_equal( 42, [a.arg,b.arg].max * 10 + c.arg )
end
end
#
# EXAMPLE B - MODIFY AN EXISTING CLASS, SHARED FILEHANDLES
#
class TC_Multiton_B < Test::Unit::TestCase
class ::File
include Multiton
end
def test_modify_existing
lineno = __LINE__
# HERE1
# HERE2
a = File.instance(__FILE__)
b = File.instance(__FILE__)
assert_equal( a, b )
lineno.times{ a.gets }
assert_equal( "# HERE1", a.gets.strip )
assert_equal( "# HERE2", b.gets.strip )
end
end
#
# EXAMPLE C - INHERITENCE
#
class TC_Multiton_C < Test::Unit::TestCase
class A < String
include Multiton
end
# B is also a multiton - with it's OWN object cache
class B < A; end
def test_inheritence
# w is the same object as x, y is the same object as z
w,x,y,z = A.instance('A'), A.instance('A'), B.instance('B'),
B.instance('B')
assert_equal( w.object_id, x.object_id ) # -> true
assert_equal( y.object_id, z.object_id ) # -> true
a = B.instance('A')
b = B.instance('A')
assert_not_equal( a.object_id, w.object_id ) # -> false (each
class has it's own pool)
assert_equal( a.object_id, b.object_id ) # -> true
end
end
#
# EXAMPLE D - MULTIPLE MODULE INCLUSION (does nothing)
#
class TC_Multiton_D < Test::Unit::TestCase
class A < String
include Multiton
end
# B is also a multiton - with it's OWN object cache
class B < A; end
def test_multiple
# w is the same object as x, y is the same object as z
w,x,y,z = A.instance('A'), A.instance('A'), B.instance('B'),
B.instance('B')
yz_id = y.object_id || z.object_id
B.class_eval {
include Multiton
}
# y is not only the same object as z, but they are both the same object(s)
# as from EXAMPLE C
y,z = B.instance('B'), B.instance('B')
assert_equal( y.object_id, yz_id ) # -> true
assert_equal( z.object_id, yz_id ) # -> true
end
end
#
# EXAMPLE E - SO YOU WANNA USE NEW INSTEAD OF INSTANCE...
#
class TC_Multiton_E < Test::Unit::TestCase
module K
# use an inner class which is itself a multiton
class K < String; include Multiton; end
# define a new which returns a mutltion using #instance...
class << self
def new(*args, &block)
K.instance *args, &block
end
end
end
def test_new
the = K.new '4'
answer = K.new '2'
assert_equal( "42", sprintf( "%s%s", the, answer ) ) #-> 42
assert_equal( K::K, the.class ) #-> K::K
end
end
#
# EXAMPLE F - using Klass.multiton_id
#
class TC_Multiton_F < Test::Unit::TestCase
class Klass
include Multiton
def initialize( important, not_important )
@important, @not_important = important, not_important
end
def Klass.multiton_id(*args, &block)
# we consider only the first arg
important, not_important = *args
important
end
end
def test_using_id
a = Klass.instance( :a, :b )
b = Klass.instance( :a, :c )
c = Klass.instance( :b, :b )
assert_equal( a, b )
assert_not_equal( a, c )
assert_not_equal( b, c )
end
end
=end
# Author:: Ara T. Howard, Thomas Sawyer
# Copyright:: Copyright (c) 2005-2007 Ara T. Howard, Thomas Sawyer
# License:: Ruby License