Nested scopes and the Singleton pattern

Hello all,

This is really two questions.

I’ve been putting together a nested class structure in pieces
since it is a little large and unwieldy.

Here’s a snippet of something I’ve run across.

By the way, my last change was to implement a simple version of the
Singleton pattern (without using singleton.rb).

Note: Reopening existing classes

class ABC
class XYZ
@@instance = nil
def initialize(foo)
# Do some stuff…
# and then:
def XYZ.new(foo)
@@instance
end
end
end
end

This works fine.

First question: Is this a valid way to implement Singleton, or am I
overlooking something?

Then I thought: Well, let’s get rid of the unnecessary verbiage.
(Remember, I’m REOPENING these classes.)

So I did:

Note: Reopening existing classes

class ABC::XYZ
@@instance = nil
def initialize(foo)
# Do some stuff…
# and then:
def ABC::XYZ.new(foo)
@@instance
end
end
end

But it didn’t work.

This does work:

Note: Reopening existing classes

class ABC::XYZ
@@instance = nil
def initialize(foo)
# Do some stuff…
# and then:
klass = ABC::XYZ
def klass.new(foo)
@@instance
end
end
end

Second question: Why should these two be different?

Thanks,
Hal Fulton

Hi,

By the way, my last change was to implement a simple version of the
Singleton pattern (without using singleton.rb).

Note: Reopening existing classes

class ABC
class XYZ
@@instance = nil
def initialize(foo)
# Do some stuff…
# and then:
def XYZ.new(foo)
@@instance
end
end
end
end

This works fine.

First question: Is this a valid way to implement Singleton, or am I
overlooking something?

Have you considered about race conditions?

So I did:

Note: Reopening existing classes

class ABC::XYZ
@@instance = nil
def initialize(foo)
# Do some stuff…
# and then:
def ABC::XYZ.new(foo)
@@instance
end
end
end

But it didn’t work.

def ABC::XYZ means singleton method XYZ of ABC by itself, so
trailing . is superfluous. Try

   def (ABC::XYZ).new(foo)
···

At Thu, 15 Jan 2004 06:40:07 +0900, Hal Fulton wrote:


Nobu Nakada

First question: Is this a valid way to implement Singleton, or am I
overlooking something?

Have you considered about race conditions?

Thank you, Nobu. No, I did not consider race conditions.

I suppose singleton.rb is thread safe?

def ABC::XYZ means singleton method XYZ of ABC by itself, so
trailing . is superfluous. Try

   def (ABC::XYZ).new(foo)

Ahh, that is clear. But I could not see it before.

Thanks very much,
Hal

···

nobu.nokada@softhome.net wrote:

Hi,

···

At Thu, 15 Jan 2004 13:24:19 +0900, Hal Fulton wrote:

First question: Is this a valid way to implement Singleton, or am I
overlooking something?

Have you considered about race conditions?

Thank you, Nobu. No, I did not consider race conditions.

I suppose singleton.rb is thread safe?

Just using Thread.critical. And seems close to your idea
excepting for it uses “instance” method rather than “new”.


Nobu Nakada

Actually I like “new” instead of “instance”. I guess this
(instance) is to emphasize that there can only be one. But
I prefer simply calling new as usual, which was why I did this.

Hal

···

nobu.nokada@softhome.net wrote:

Hi,

At Thu, 15 Jan 2004 13:24:19 +0900, > Hal Fulton wrote:

First question: Is this a valid way to implement Singleton, or am I
overlooking something?

Have you considered about race conditions?

Thank you, Nobu. No, I did not consider race conditions.

I suppose singleton.rb is thread safe?

Just using Thread.critical. And seems close to your idea
excepting for it uses “instance” method rather than “new”.

Hi,

I suppose singleton.rb is thread safe?

Just using Thread.critical. And seems close to your idea
excepting for it uses “instance” method rather than “new”.

Not accurate, it uses 3-state; before, during and after
creation, but I feel it should use mutex or something.

Actually I like “new” instead of “instance”. I guess this
(instance) is to emphasize that there can only be one. But
I prefer simply calling new as usual, which was why I did this.

singleton.rb is for generic use, so it gets rid of overriding
instance methods, I guess.

···

At Thu, 15 Jan 2004 13:55:44 +0900, Hal Fulton wrote:


Nobu Nakada

I think I agree. It took me an hour to understand the Singleton code
last time I read it, and when I look at it again now, I seem to have
forgotten how it works.

It seems like using a Mutex plus Thread.exclusive around the code that
redefines instance() should be sufficient, but perhaps I’m missing
something.

Paul

···

On Thu, Jan 15, 2004 at 06:39:13PM +0900, nobu.nokada@softhome.net wrote:

At Thu, 15 Jan 2004 13:55:44 +0900, > Hal Fulton wrote:

Just using Thread.critical. And seems close to your idea
excepting for it uses “instance” method rather than “new”.

Not accurate, it uses 3-state; before, during and after
creation, but I feel it should use mutex or something.

nobu wrote

Just using Thread.critical. And seems close to your idea
excepting for it uses “instance” method rather than “new”.

Not accurate, it uses 3-state; before, during and after
creation, but I feel it should use mutex or something.

You probably always need a 3-state if you want a self
modifying first instance call (at least in some implicit way).

Here is a mutexy version of singleton.rb I wrote some time
ago - it is probably more robust then the current code but equally
obscure - sorry …

/Christoph

begin 666 singleton.diff
M+2TM(‘-I;F=L971O;BYR8BYO;&0),C P,RTP.“TR,B Q,#HP.3HU.“XP,# P
M,# P,# @S R,# **RLK('-I;F=L971O;BYR8@DR,# T+3 Q+3$U(#(S.C$W
M.C4X+C8S,C,Y-S8P," K,#$P, I 0" M,2PS-C @S$L,S(Q($! "BTC(%1H
M92!3:6YG;&5T;VX@;6]D=6QE(&EM<&QE;65N=',@=&AE(%-I;F=L971O;B!P
M871T97)N+@HM(PHM(R!5<V%G93H
+2,@(" @8VQA<W,@2VQA<W,
+2,@(” @
M(” @:6YC;‘5D92!3:6YG;&5T;VX*+2,@(" @(" @(R N+BX*+2,@(" @96YD
M"BTC"BTC(“H@('1H:7,@96YS=7)E<R!T:&%T(&]N;‘D@;VYE(&EN<W1A;F-E
M(&]F($ML87-S(&QE=’,@8V%L;”!I= HM(R @(“!@8’1H92!I;G-T86YC92<G
M(&-A;B!B92!C<F5A=&5D+@HM(PHM(R @(”!A+&(@(#T@2VQA<W,N:6YS=&%N
M8V4L($ML87-S+FEN<W1A;F-E"BTC(" @(&$@/3T@8B @(",@/3X@=’)U90HM
M(R @(“!A+FYE=R @(” C("!.;TUE=&AO9$5R<F]R("T@;F5W(&ES(’!R:79A
M=&4@+BXN"BTC"BTC(“H@(&!@5&AE(&EN<W1A;F-E)R<@:7,@8W)E871E9”!A
M=“!I;G-T86YC:6%T:6]N('1I;64L(&EN(&]T:&5R"BTC(” @(‘=O<F1S(‘1H
M92!F:7)S=“!C86QL(&]F($ML87-S+FEN<W1A;F-E*“DL('1H=7,+2,+2,@
M(” @8VQA<W,@3W1H97)+;&%S<PHM(R @(” @(" @:6YC;‘5D92!3:6YG;&5T
M;VX*+2,@(" @(" @(“,@+BXN"BTC(” @(&5N9 HM(R @("!/8FIE8W13<&%C
M92YE86-H7V]B:F5C="A/=&AE<DML87-S7M](",@/3X@,"X+2,+2,@B @
M5&AI<R!B96AA=FEO<B!I<R!P<F5S97)V960@=6YD97(@:6YH97)I=&%N8V4@
M86YD(&-L;VYI;F<N"BTC"BTC"BTC"BTC(%1H:7,@:7,@86-H:65V960@8GD@
M;6%R:VEN9PHM(R J("!+;&%S<RYN97<@86YD($ML87-S+F%L;&]C871E("T@
M87,@<')I=F%T90HM(PHM(R!0<F]V:61I;F<@
&]R(&UO9&EF>6EN9RD@=&AE
M(&-L87-S(&UE=&AO9’,
+2,@B @2VQA<W,N:6YH97)I=&5D’-U8E]K;&%S
M<RD@86YD($ML87-S+F-L;VYE*“D@(“T@“BTC(” @('1O(&5N<W5R92!T:&%T
M('1H92!3:6YG;&5T;VX@<&%T=&5R;B!I<R!P<F]P97)L>0HM(R @(”!I;FAE
M<FET960@86YD(&-L;VYE9"X*+2,+2,@B @2VQA<W,N:6YS=&%N8V4H2 @
M+2 @<F5T=7)N:6YG(&!@=&AE(&EN<W1A;F-E)R<N($%F=&5R(&$
+2,@(” @
M<W5C8V5S<V9U;“!S96QF(&UO9&EF>6EN9R H;F]R;6%L;'D@=&AE(&9I<G-T
M2!C86QL(‘1H90HM(R @("!M971H;V0@8F]D>2!I<R!A(’-I;7!L93H+2,*
M+2,@(” @(" @9&5F($ML87-S+FEN<W1A;F-E*“D*+2,@(” @(" @(“!R971U
M<FX@0%]?:6YS=&%N8V5?7PHM(R @(” @("!E;F0*+2,+2,@B @2VQA<W,N
M7VQO860H<W1R
2 @+2 @8V%L;&EN9R!+;&%S<RYI;G-T86YC92@I"BTC"BTC
M("H@($ML87-S+E]I;G-T86YC:6%T93\H
2 @+2 @<F5T=7)N:6YG(&!@=&AE
M(&EN<W1A;F-E)R<@;W(+2,@(" @;FEL+B!4:&ES(&AO;VL@;65T:&]D(‘!U
M=’,@82!S96-O;F0@
&]R(&YT:"D@=&AR96%D(&-A;&QI;F<+2,@(" @2VQA
M<W,N:6YS=&%N8V4H
2!O;B!A(’=A:71I;F<@;&]O<"X@5&AE(’)E=‘5R;B!V
M86QU90HM(R @("!S:6=N:69I97,@=&AE(’-U8V-E<W-F=6P@8V]M<&QE=&EO
M;B!O<B!P<F5M871U<F4@=&5R;6EN871I;VX*+2,@(" @;V8@=&AE(&9I<G-T
M+“!O<B!M;W)E(&=E;F5R86QL>2P@8W5R<F5N=” B:6YS=&%N8VEA=&EO;B!T
M:‘)E860B+@HM(PHM(PHM(R!4:&4@:6YS=&%N8V4@;65T:&]D(&]F(%-I;F=L
M971O;B!A<F4*+2,@B!C;&]N92!A;F0@9’5P("T@<F%I<VEN9R!4>7!E17)R
M;W)S(‘1O(’!R979E;G0@8VQO;FEN9R!O<B!D=7!I;F<
+2,+2,@B @7V1U
M;7 H9&5P=&@I(“T@<F5T=7)N:6YG(‘1H92!E;7!T>2!S=’)I;F<N(”!-87)S
M:&%L;&EN9R!S=‘)I<’,
+2,@(" @8GD@9&5F875L=“!A;&P@<W1A=&4@:6YF
M;W)M871I;VXL(&4N9RX@:6YS=&%N8V4@=F%R:6%B;&5S(&%N9 HM(R @(”!T
M86EN=“!S=&%T92P@9G)O;2!@8’1H92!I;G-T86YC92<G+B @4’)O=FED:6YG
M(&-U<W1O;2!?;&]A9"AS='(I"BTC(” @(&%N9"!?9’5M<"AD97!T:"D@:&]O
M:W,@86QL;W=S('1H92 H<&%R=&EA;&QY
2!R97-U<G)E8W1I;VYS(&]F"BTC
M(" @(&$@<’)E=FEO=7,@<W1A=&4@;V8@8&!T:&4@:6YS=&%N8V4G)RX*+0HM
M"BT*+6UO9’5L92!3:6YG;&5T;VX*+2 @(R @9&ES86)L92!B=6EL9"UI;B!C
M;W!Y:6YG(&UE=&AO9’,+2 @9&5F(&-L;VYE"BT@(" @<F%I<V4@5’EP945R
M<F]R+" B8V%N)W0@8VQO;F4@:6YS=&%N8V4@;V8@<VEN9VQE=&]N(“-[<V5L
M9BYC;&%S<WTB"BT@(&5N9 HM(”!D968@9’5P"BT@(" @<F%I<V4@5’EP945R
M<F]R+" B8V%N)W0@9’5P(&EN<W1A;F-E(&]F('-I;F=L971O;B C>W-E;&8N
M8VQA<W-](@HM("!E;F0
+2 @“BT@('!R:79A=&4@“BT@(”,@(&1E9F%U;'0@
M;6%R<VAA;&QI;F<@<W1R871E9WD*+2 @9&5F(%]D=6UP*&1E<'1H/2TQ2 *
M+2 @(" G)PHM("!E;F0
+65N9 HM"BT*+6-L87-S(#P(%-I;F=L971O;@HM
M(” C(“!-971H;V0@8F]D>2!O9B!F:7)S=”!I;G-T86YC92!C86QL+@HM(“!&
M:7)S=$EN<W1A;F-E0V%L;” ](‘!R;V,@9&*+2 @(" C(“! 7U]I;G-T86YC
M95]?('1A:V5S(&]N(&]N92!O9B!T:&4@9F]L;&]W:6YG('9A;'5E<PHM(” @
M(“,@(“H@;FEL(” @(” M(“!B969O<F4@86YD(&%F=&5R(&$@9F%I;&5D(&-R
M96%T:6]N"BT@(” @(R @B!F86QS92 @+2 @9’5R:6YG(&-R96%T:6]N"BT@
M(" @(R @B!S=6)?8VQA<W,@:6YS=&%N8V4@(“T@(&%F=&5R(&$@<W5C8V5S
M<V9U;”!C<F5A=&EO;@HM(" @(“,@('1H92!F;W)M(&UA:V5S(‘5P(&9O<B!T
M:&4@;&%C:R!O9B!R971U<FYS(&EN(’!R;V=S"BT@(” @5&AR96%D+F-R:71I
M8V%L(#T@=')U90HM(" @(&EF(“! 7U]I;G-T86YC95]?+FYI;#*+2 @(” @
M($!?7VEN<W1A;F-E7U@(#T@9F%L<V4
+2 @(" @(%1H<F5A9"YC<FET:6-A
M;" ](&9A;'-E"BT@(" @(“!B96=I;@HM(” @(" @(“! 7U]I;G-T86YC95]?
M(#T@;F5W"BT@(” @("!E;G-U<F4
+2 @(" @(" @:68@0%]?:6YS=&%N8V5?
M7PHM(" @(" @(" @(&-L87-S(#P<V5L9@HM(" @(" @(" @(" @<F5M;W9E
M7VUE=&AO9" Z:6YS=&%N8V4*+2 @(" @(" @(" @(&1E9B!I;G-T86YC93L@
M0%]?:6YS=&%N8V5?7R!E;F0*+2 @(" @(" @(“!E;F0*+2 @(” @(" @96QS
M90HM(" @(" @(" @($!?7VEN<W1A;F-E7U@/2!N:6P@(R @9F%I;&5D(&EN
M<W1A;F-E(&-R96%T:6]N"BT@(" @(" @(&5N9 HM(" @(" @96YD"BT@(" @
M96QS:68@(%]I;G-T86YC:6%T93\H0HM(" @(" @5&AR96%D+F-R:71I8V%L
M(#T@9F%L<V4@(" @“BT@(” @96QS90HM(" @(" @0%]?:6YS=&%N8V5?7R @
M/2!F86QS90HM(" @(" @5&AR96%D+F-R:71I8V%L(#T@9F%L<V4
+2 @(" @
M(&)E9VEN"BT@(" @(" @($!?7VEN<W1A;F-E7U@/2!N97<+2 @(" @(&5N
M<W5R90HM(" @(" @(“!I9B! 7U]I;G-T86YC95]?“BT@(” @(” @(" @8VQA
M<W,@/#QS96QF"BT@(" @(" @(" @(“!R96UO=F5?;65T:&]D(#II;G-T86YC
M90HM(” @(" @(" @(" @9&5F(&EN<W1A;F-E.R! 7U]I;G-T86YC95]?(&5N
M9 HM(" @(" @(" @(&5N9 HM(" @(" @(“!E;'-E"BT@(” @(" @(" @0%]?
M:6YS=&%N8V5?7R ](&YI; HM(" @(" @("!E;F0
+2 @(" @(&5N9 HM(" @
M(&5N9 HM(" @($!?7VEN<W1A;F-E7U*+2 @96YD"BT@( HM(“!M;V1U;&4@
M4VEN9VQE=&]N0VQA<W–971H;V1S(” +2 @(" C('!R;W!E<FQY(&-L;VYE
M(‘1H92!3:6YG;&5T;VX@<&%T=&5R;B M(&1I9"!Y;W4@:VYO=PHM(" @(“,@
M=&AA=”!D=7!I;F<@9&]E<VXG="!C;W!Y(&-L87-S(&UE=&AO9’,_(" +2 @
M("!D968@8VQO;F4
+2 @(" @(%-I;F=L971O;BY?7VEN:71?7RAS=7!E<BD

M+2 @(“!E;F0*+2 @(” +2 @(“!P<FEV871E"BT@(” @“BT@(” @(R @96YS
M=7)E(‘1H870@=&AE(%-I;F=L971O;B!P871T97)N(&ES(’!R;W!E<FQY(&EN
M:&5R:71E9" @( HM(" @(&1E9B!I;FAE<FET960H<W5B7VML87-S
0HM(" @
M(" @<W5P97(+2 @(" @(%-I;F=L971O;BY?7VEN:71?7RAS=6)?:VQA<W,I
M"BT@(" @96YD"BT@(" @“BT@(” @9&5F(%]L;V%D
’-T<BD@“BT@(” @(“!I
M;G-T86YC92 +2 @("!E;F0+2 @(” +2 @(" C('=A:71I;F<M;&]O<“!H
M;V]K"BT@(” @9&5F(%]I;G-T86YC:6%T93\H
0HM(" @(" @=VAI;&4@9F%L
M<V4N97%U86P_$!?7VEN<W1A;F-E7U\I"BT@(" @(" @(%1H<F5A9"YC<FET
M:6-A;" ](&9A;‘-E"BT@(" @(" @(’-L965P
# N,#@I(" @(R!T:6UE;W5T
M"BT@(" @(" @(%1H<F5A9"YC<FET:6-A;" ](‘1R=64*+2 @(" @(&5N9 HM
M(" @(" @0%]?:6YS=&%N8V5?7PHM(" @(&5N9 HM(“!E;F0*+2 @“BT@(&1E
M9B!?7VEN:71?7RAK;&%S<RD*+2 @(”!K;&%S<RYI;G-T86YC95]E=F%L('L@
M0%]?:6YS=&%N8V5?7R ](&YI;”!]“BT@(” @8VQA<W,@/#P@:VQA<W,+2 @
M(" @(&1E9FEN95]M971H;V0H.FEN<W1A;F-E+$9I<G-T26YS=&%N8V5#86QL
M
0HM(" @(&5N9 HM(" @(&ML87-S"BT@(&5N9 HM(" +2 @<')I=F%T90HM
M(" C("!E>‘1E;F1I;F<@86X@;V)J96-T(’=I=&@@4VEN9VQE=&]N(&ES(&$@
M8F%D(&ED96$
+2 @=6YD969?;65T:&]D(#IE>‘1E;F1?;V)J96-T"BT@( HM
M(“!D968@87!P96YD7V9E871U<F5S*&UO9"D*+2 @(” C(“!H96QP(&]U=”!P
M96]P;&4@8V]U;G1I;F<@;VX@=’)A;G-I=&EV92!M:7AI;G,+2 @("!U;FQE
M<W,@;6]D+FEN<W1A;F-E7V]F/RA#;&%S<RD
+2 @(" @(’)A:7-E(%1Y<&5%
M<G)O<BP@(DEN8VQU<VEO;B!O9B!T:&4@3T\M4VEN9VQE=&]N(&UO9’5L92!I
M;B!M;V1U;&4@(WMM;V1](@HM(" @(&5N9 HM(" @(‘-U<&5R"BT@(&5N9 HM
M(" +2 @9&5F(&EN8VQU9&5D&ML87-S0HM(" @(‘-U<&5R"BT@(" @:VQA
M<W,N<’)I=F%T95]C;&%S<U]M971H;V0@(#IN97<L(#IA;&QO8V%T90HM(" @
M(&ML87-S+F5X=&5N9"!3:6YG;&5T;VY#;&%S<TUE=&AO9’,
+2 @("!3:6YG
M;&5T;VXN7U]I;FET7U\H:VQA<W,I"BT@(&5N9 HM96YD"BT@"BT*+0HM:68@
M7U]&24Q%7U@/3T@)# +0HM9&5F(&YU;5]O9E]I;G-T86YC97,H:VQA<W,I
M"BT@(" @(B-[3V)J96-T4W!A8V4N96%C:%]O8FIE8W0H:VQA<W,I>WU]("-[
M:VQA<W-](&EN<W1A;F-E
’,I(@HM96YD( HM"BTC(%1H92!B87-I8R!A;F0@
M;6]S=“!I;7!O<G1A;G0@97AA;7!L92X*+0HM8VQA<W,@4V]M95-I;F=L971O
M;D-L87-S"BT@(&EN8VQU9&4@4VEN9VQE=&]N"BUE;F0*+7!U=‘,@(E1H97)E
M(&%R92 C>VYU;5]O9E]I;G-T86YC97,H4V]M95-I;F=L971O;D-L87-S7TB
M( HM"BUA(#T@4V]M95-I;F=L971O;D-L87-S+FEN<W1A;F-E"BUB(#T@4V]M
M95-I;F=L971O;D-L87-S+FEN<W1A;F-E(",@82!A;F0@8B!A<F4@<V%M92!O
M8FIE8W0
+7!U=’,@(F)A<VEC('1E<W0@:7,@(WMA(#T](&)](@HM"BUB96=I
M;@HM(”!3;VUE4VEN9VQE=&]N0VQA<W,N;F5W"BUR97-C=64@($YO365T:&]D
M17)R;W(@/3X@;65S"BT@(‘!U=’,@;65S"BUE;F0*+0HM"BT*+7!U=‘,@(EQN
M5&AR96%D960@97AA;7!L92!W:71H(&5X8V5P=&EO;B!A;F0@8W5S=&]M:7IE
M9" C7VEN<W1A;F-I871E/R@I(&AO;VLB.R!P"BU4:’)E860N86)O<G1?;VY?
M97AC97!T:6]N(#T@9F%L<V4*+0HM8VQA<W,@57!S(#P@4V]M95-I;F=L971O
M;D-L87-S"BT@(&1E9B!I;FET:6%L:7IE"BT@(" @<V5L9BYC;&%S<RY?7W-L
M965P"BT@(" @<'5T<R B:6YI=&EA;&EZ92!C86QL960@8GD@=&AR96%D(",C

U1H<F5A9"YC=7)R96YT6SII77TB"BT@(&5N9 HM96YD"BT@( HM8VQA<W,@
M/#P@57!S"BT@(&1E9B!?:6YS=&%N8VEA=&4_“BT@(” @0&5N=&5R+G!U<V@@
M5&AR96%D+F-U<G)E;G1;.FE=“BT@(” @=VAI;&4@9F%L<V4N97%U86P_$!?
M7VEN<W1A;F-E7U\I"BT@(" @(“!4:')E860N8W)I=&EC86P@/2!F86QS90HM
M(” @(" @<VQE97 @,“XP.” +2 @(" @(%1H<F5A9"YC<FET:6-A;" ]('1R
M=64
+2 @("!E;F0
+2 @(“! ;&5A=F4N<'5S:”!4:‘)E860N8W5R<F5N=%LZ
M:5T*+2 @(“! 7U]I;G-T86YC95]?“BT@(&5N9 HM(” +2 @9&5F(%]?<VQE
M97 +2 @("!S;&5E<"AR86YD# N,#@I
0HM(”!E;F0*+2 @“BT@(&1E9B!N
M97<+2 @(“!B96=I;@HM(” @(" @7U]S;&5E< HM(" @(" @<F%I<V4@(")B
M;V]M(“T@=&AR96%D(”,C>U1H<F5A9"YC=7)R96YT6SII77T@9F%I;&5D('1O
M(&-R96%T92!I;G-T86YC92(
+2 @(”!E;G-U<F4*+2 @(" @(“,@<VEM<&QE
M(&9L:7 M9FQO< HM(” @(" @8VQA<W,@/#P@<V5L9@HM(" @(" @(“!R96UO
M=F5?;65T:&]D(#IN97<+2 @(" @(&5N9 HM(" @(&5N9 HM("!E;F0+2 @
M"BT@(&1E9B!I;G-T86YC:6%T95]A;&P*+2 @(”! 96YT97(@/2!;70HM(" @
M($!L96%V92 ](%M=“BT@(” @,2YU<‘1O*#DI(‘M:7P@( HM(" @(" @5&AR
M96%D+FYE=R![( HM(" @(" @(“!B96=I;@HM(” @(" @(" @(%1H<F5A9"YC
M=7)R96YT6SII72 ](&D*+2 @(" @(" @(“!?7W-L965P"BT@(” @(" @(" @
M:6YS=&%N8V4*+2 @(" @(" @<F5S8W5E(%)U;G1I;65%<G)O<B ]/B!M97,*
M+2 @(" @(" @(“!P=71S(&UE<PHM(” @(" @(“!E;F0*+2 @(” @(‘T*+2 @
M(“!]“BT@(” @<‘5T<R B0F5F;W)E(‘1H97)E(’=E<F4@(WMN=6U?;V9?:6YS
M=&%N8V5S*’-E;&8I?2(+2 @(“!S;&5E<” S"BT@(" @<'5T<R B3F]W('1H
M97)E(&ES("-[;G5M7V]F7VEN<W1A;F-E<RAS96QF
7TB"BT@(” @<‘5T<R B
M(WM 96YT97(N:F]I;B G.R G?2!W87,@=&AE(&]R9&5R(&]F(‘1H<F5A9’,@
M96YT97)I;F<@=&AE(’=A:71I;F<@;&]O<“(+2 @(“!P=71S(”(C>T!L96%V
M92YJ;VEN("<("=D97(@;V8@=&AR96%D<R!L96%V:6YG
M('1H92!W86ET:6YG(&QO;W B"BT@(&5N9 HM96YD"BT
+0HM57!S+FEN<W1A
M;F-I871E7V%L; HM(R!R97-U;‘1S(&EN(&UE<W-A9V4@;&EK90HM(R!“969O
M<F4@=&AE<F4@=V5R92 P(%5P<R!I;G-T86YC92AS0HM(R!B;V]M(“T@=&AR
M96%D(”,V(&9A:6QE9"!T;R!C<F5A=&4@:6YS=&%N8V4
+2,@:6YI=&EA;&EZ
M92!C86QL960@8GD@=&AR96%D(”,S"BTC($YO=R!T:&5R92!I<R Q(%5P<R!I
M;G-T86YC92AS0HM(R S.R R.R Q.R X.R T.R W.R U(‘=A<R!T:&4@;W)D
M97(@;V8@=&AR96%D<R!E;G1E<FEN9R!T:&4@=V%I=&EN9R!L;V]P"BTC(#,[
M(#([(#$[(#<[(#0[(#@[(#4@=V%S(‘1H92!O<F1E<B!O9B!T:’)E861S(&QE
M879I;F<@=&AE(’=A:71I;F<@;&]O< HM"BT
+7!U=’,@(EQN3&5T<R!S964@
M:68@8VQA<W,@;&5V96P@8VQO;FEN9R!R96%L;‘D@=V]R:W,B"BU9=7 @/2!5
M<’,N8VQO;F4*+61E9B!9=7 N;F5W"BT@(&)E9VEN"BT@(” @7U]S;&5E< HM
M(" @(’)A:7-E(" B8F]O;2 M(‘1H<F5A9" C(WM4:’)E860N8W5R<F5N=%LZ
M:5U](&9A:6QE9"!T;R!C<F5A=&4@:6YS=&%N8V4B"BT@(&5N<W5R90HM(" @
M(“,@<VEM<&QE(&9L:7 M9FQO< HM(” @(&-L87-S(#P(’-E;&8*+2 @(" @
M(’)E;6]V95]M971H;V0@.FYE=PHM(" @(&5N9 HM("!E;F0*+65N9 HM675P
M+FEN<W1A;F-I871E7V%L; HM"BT*+7!U=’,@(EQN7&XB+“)#=7-T;VUI>F5D
M(&UA<G-H86QL:6YG(@HM8VQA<W,@00HM(”!I;F-L=61E(%-I;F=L971O;@HM
M(“!A='1R7V%C8V5S<V]R(#IP97)S:7-T+” Z9&EE"BT@(&1E9B!?9’5M<“AD
M97!T:“D*+2 @(” C('1H:7,@<W1R:7!S('1H92! 9&EE(&EN9F]R;6%T:6]N
M(&9R;VT@=&AE(&EN<W1A;F-E"BT@(” @36%R<VAA;“YD=6UP*$!P97)S:7-T
M+&1E<‘1H0HM("!E;F0+65N9 HM"BUD968@02Y?;&]A9"AS=’(I"BT@(&EN
M<W1A;F-E+G!E<G-I<W0@/2!-87)S:&%L+FQO860H<W1R0HM("!I;G-T86YC
M90HM96YD"BT
+6$@/2!!+FEN<W1A;F-E"BUA+G!E<G-I<W0@/2!;(G!E<G-I
M<W0B70HM82YD:64@/2 B9&EE(@HM82YT86EN= HM"BUS=&]R961?<W1A=&4@
M/2!-87)S:&%L+F1U;7 H82D*+2,@8VAA;F=E(‘-T871E"BUA+G!E<G-I<W0@
M/2!N:6P*+6$N9&EE(#T@;FEL"BUB(#T@36%R<VAA;"YL;V%D*’-T;W)E9%]S
M=&%T92D*+7 @82 ]/2!B(” C(" ]/B!T<G5E"BUP(&$N<&5R<VES=" @(R @
M/3X@6R)P97)S:7-T(ET*+7 @82YD:64@(" @(" C(" ]/B!N:6P*+0HM"BUP
M=71S(“)<;EQN4VEN9VQE=&]N('=I=&@@;W9E<G)I9&1E;B!D969A=6QT(”-I
M;FAE<FET960H2!H;V]K(@HM8VQA<W,@57 +65N9 HM9&5F(%5P+FEN:&5R
M:71E9"AS=6)?:VQA<W,I"BT@(‘!U=’,@(B-[<W5B7VML87-S?2!S=6)C;&%S
M<V5S("-[<V5L9GTB"BUE;F0
+0HM"BUC;&%S<R!-:61D;&4@/“!5< HM(”!I
M;F-L=61E(%-I;F=L971O;@HM96YD"BT
+6-L87-S($1O=VX@/“!-:61D;&4[
M(&5N9 HM"BUP=71S(” B86YD(&)A<VEC(%PB1&]W;B!T97-T7"(@:7,@(WM$
M;W=N+FEN<W1A;F-E(#T]($1O=VXN:6YS=&%N8V5]7&X*+59A<FEO=7,@97AC
M97!T:6]N<R(@( HM"BUB96=I;@HM(“!M;V1U;&4@04UO9’5L90HM(” @(&EN
M8VQU9&4@4VEN9VQE=&]N"BT@(&5N9 HM<F5S8W5E(%1Y<&5%<G)O<B ]/B!M
M97,+2 @<'5T<R!M97,@(",]/B!);F-L=7-I;VX@;V8@=&AE($]/+5-I;F=L
M971O;B!M;V1U;&4@:6X@;6]D=6QE($%-;V1U;&4
+65N9 HM"BUB96=I;@HM
M(" G85-T<FEN9R<N97AT96YD(%-I;F=L971O;@HM<F5S8W5E($YO365T:&]D
M17)R;W(@/3X@;65S"BT@(‘!U=’,@;65S(" C/3X@=6YD969I;F5D(&UE=&AO
M9"!@97AT96YD7V]B:F5C=“<@9F]R(%-I;F=L971O;CI-;V1U;&4*+65N9 HM
M"BUE;F0R,@5&AE(%-I;F=L971O;B!M;V1U;&4@:6UP;&5M96YT<R!T:&4@
M4VEN9VQE=&]N('!A='1E<FXN#0HK(PT
R,@57-A9V4Z#0HK(R @(”!C;&%S
M<R!+;&%S<PTR,@(" @(" @:6YC;'5D92!3:6YG;&5T;VX-“BLC(” @(" @
M(“,@+BXN#0HK(R @(”!E;F0-“BLC#0HK(R J(”!T:&ES(&5N<W5R97,@=&AA
M="!O;FQY(&]N92!I;G-T86YC92!O9B!+;&%S<R!L971S(&-A;&P@:70-“BLC
M(” @(&!@=&AE(&EN<W1A;F-E)R<@8V%N(&)E(&-R96%T960N#0HK(PT
R,@
M(" @82QB(" ]($ML87-S+FEN<W1A;F-E+“!+;&%S<RYI;G-T86YC90TR,@
M(" @82 ]/2!B(" @(R ]/B!T<G5E#0HK(R @(“!+;&%S<RYN97<@(” @(R @
M3F]-971H;V1%<G)O<B M(&YE=R!I<R!P<FEV871E("XN+@T
R,-“BLC(“H@
M(&!@5&AE(&EN<W1A;F-E)R<@:7,@8W)E871E9”!A=”!I;G-T86YC:6%T:6]N
M('1I;64L(&EN(&]T:&5R#0HK(R @(”!W;W)D<R!T:&4@9FER<W0@8V%L;“!O
M9B!+;&%S<RYI;G-T86YC92@I+”!T:‘5S#0HK(PTR,@(" @8VQA<W,@3W1H
M97)+;&%S<PT
R,@(" @(" @(&EN8VQU9&4@4VEN9VQE=&]N#0HK(R @(" @
M(" @(R N+BX-“BLC(” @(&5N9 TR,@(" @3V)J96-T4W!A8V4N96%C:%]O
M8FIE8W0H3W1H97)+;&%S<RE[?2 C(#T^(# N#0HK(PT
R,@B @5&AI<R!B
M96AA=FEO<B!I<R!P<F5S97)V960@=6YD97(@:6YH97)I=&%N8V4@86YD(&-L
M;VYI;F<N#0HK(PTR,-"BLC#0HK(R!4:&ES(&ES(&%C:&EE=F5D(&)Y(&UA
M<FMI;F<-"BLC("H@($ML87-S+FYE=R!A;F0@2VQA<W,N86QL;V-A=&4@+2!A
M<R!P<FEV871E#0HK(PT
R,@4’)O=FED:6YG(“AO<B!M;V1I9GEI;F<I('1H
M92!C;&%S<R!M971H;V1S#0HK(R J(”!+;&%S<RYI;FAE<FET960H<W5B7VML
M87-S
2!A;F0@2VQA<W,N:6YI=&EA;&EZ95]C;W!Y*“D-“BLC#0HK(R J(”!+
M;&%S<RYI;G-T86YC92@I(” M(“!R971U<FYI;F<@8&!T:&4@:6YS=&%N8V4G
M)RX@069T97(@80TR,@(" @<W5C8V5S<V9U;"!S96QF(&UO9&EF>6EN9R H
M;F]R;6%L;'D@=&AE(&9I<G-T*2!C86QL('1H90T
R,@(” @;65T:&]D(&)O
M9’D@:7,@82!S:6UP;&4Z#0HK(PTR,@(" @(" @9&5F($ML87-S+FEN<W1A
M;F-E*“D-“BLC(” @(” @(" @<F5T=7)N($!?7VEN<W1A;F-E7U-“BLC(” @
M(" @(&5N9 T
R,-"BLC("H@($ML87-S+E]L;V%D*’-T<BD@(“T@(&-A;&QI
M;F<@2VQA<W,N:6YS=&%N8V4H0T**R,-"BLC#0HK(R!4:&4@:6YS=&%N8V4@
M;65T:&]D(&]F(%-I;F=L971O;B!A<F4-"BLC(“H@8VQO;F4@86YD(&1U<” M
M(‘)A:7-I;F<@5’EP945R<F]R<R!T;R!P<F5V96YT(&-L;VYI;F<-“BLC#0HK
M(R J(”!?9’5M<"AD97!T:"D@+2!R971U<FYI;F<@=&AE(&5M<‘1Y(’-T<FEN
M9RP@:6X@;W1H97(@=V]R9’,-“BLC(” @(&UA<G-H86QL:6YG('-T<FEP<R!A
M;&P@<W1A=&4@:6YF;W)M871I;VXN(%!R;W9I9&EN9R!C=7-T;VT-“BLC(” @
M(%]L;V%D
’-T<BD@86YD(%]D=6UP*&1E<'1H2!H;V]K<R!A;&QO=W,@=&AE
M(“AP87)T:6%L;‘DI( TR,@(" @<F5S=7)R96-T:6]N<R!O9B!A(‘!R979I
M;W5S(’-T871E(&]F(&!@=&AE(&EN<W1A;F-E)R<N#0HK#0HK#0HK;6]D=6QE
M(%-I;F=L971O;@T
R @(R @9&ES86)L92!B=6EL9"UI;B!C;W!Y:6YG(&UE
M=&AO9’,-“BL@(&1E9B!C;&]N90TR @(“!R86ES92!4>7!E17)R;W(L(”)C
M86XG="!C;&]N92!I;G-T86YC92!O9B!S:6YG;&5T;VX@(WMS96QF+F-L87-S
M?2(-"BL@(&5N9 T
R @9&5F(&1U< TR @(“!R86ES92!4>7!E17)R;W(L
M(”)C86XG=“!D=7 @:6YS=&%N8V4@;V8@<VEN9VQE=&]N(”-[<V5L9BYC;&%S
M<WTB#0HK("!E;F0-"BL@( T
R @<')I=F%T92 @#0HK(” C(”!D969A=6QT
M(&UA<G-H86QL:6YG(‘-T<F%T96=Y#0HK(“!D968@7V1U;7 H9&5P=&@]+3$I
M( TR @(" G)PTR @96YD#0HK96YD#0HK#0HK#0HK8VQA<W,@/#P@4VEN
M9VQE=&]N#0HK(” C(“!-971H;V0@8F]D>2!O9B!F:7)S=”!I;G-T86YC92!C
M86QL+@TR @1FER<W1);G-T86YC94-A;&P@/2!P<F]C('L@?‘P-“BL@(” @
M8F5G:6X-“BL@(” @(“!U;G1I;” H5&AR96%D+F-R:71I8V%L(#T@=’)U93L@
M0%]?:6YS=&%N8V5?7RD-“BL@(” @(" @(&EF($!?7VEN<W1A;F-E7U\N;FEL
M/PT
R @(" @(" @(“! 7U]I;G-T86YC95]?(#T@9F%L<V4@#0HK(” @(" @
M(" @(%1H<F5A9"YC<FET:6-A;" ](&9A;’-E#0HK(" @(" @(" @(&)E9VEN
M( TR @(" @(" @(" @($!?7VEN<W1A;F-E7U@/2!N97<-“BL@(” @(" @
M(" @96YS=7)E#0HK(" @(" @(" @(" @5&AR96%D+F-R:71I8V%L/2!T<G5E
M#0HK(" @(" @(" @(" @:68@0%]?:6YS=&%N8V5?7PT
R @(" @(" @(" @
M(" @8VQA<W,@/#P@<V5L9@TR @(" @(" @(" @(" @("!R96UO=F5?;65T
M:&]D(#II;G-T86YC90T
R @(" @(" @(" @(" @(“!D968@:6YS=&%N8V4[
M($!?7VEN<W1A;F-E7U@96YD#0HK(” @(" @(" @(" @(“!E;F0-“BL@(” @
M(” @(" @(" @($!?7VEN<W1A;F-I871I;F=?<75E=65?7RYE86-H(‘M=&AR
M?"!T:’(N=V%K975P(‘T-“BL@(” @(" @(" @(" @(’)E;6]V95]I;G-T86YC
M95]V87)I86)L92 Z0%]?:6YS=&%N8VEA=&EN9U]Q=65U95]?#0HK(" @(" @
M(" @(" @96QS90TR @(" @(" @(" @(" @0%]?:6YS=&%N8V5?7R ](&YI
M; T
R @(" @(" @(" @(" @:68@=&AR(#T@0%]?:6YS=&%N8VEA=&EN9U]Q
M=65U95]?+G-H:69T#0HK(" @(" @(" @(" @(" @('1H<BYW86ME=7 -“BL@
M(” @(" @(" @(" @(&5N9 TR @(" @(" @(" @(&5N9 TR @(" @(" @
M(“!E;F0-“BL@(” @(” @(&5L<V4-“BL@(” @(" @(" @0%]?:6YS=&%N8VEA
M=&EN9U]Q=65U95]?(#P(%1H<F5A9"YC=7)R96YT#0HK(" @(" @(" @(%1H
M<F5A9"YS=&]P#0HK(" @(" @(“!E;F0-“BL@(” @(”!E;F0-“BL@(” @(“!
M7U]I;G-T86YC95]?#0HK(” @(&5N<W5R90TR @(" @(%1H<F5A9"YC<FET
M:6-A;#T@9F%L<V4-“BL@(” @96YD#0HK(“!]#0HK(” -“BL@(&UO9’5L92!3
M:6YG;&5T;VY#;&%S<TUE=&AO9’,-“BL@(” @9&5F('-E;&8N97AT96YD960H
M:VQA<W,I#0HK(” @(" @:VQA<W,N:6YS=&%N8V5?979A;"![( T
R @(" @
M(" @0%]?:6YS=&%N8V5?7R ](&YI; TR @(" @(" @0%]?:6YS=&%N8VEA
M=&EN9U]Q=65U95]?(#T@6UT@#0HK(" @(" @?0T
R @(" @(&-L87-S(#P
M(&ML87-S#0HK(" @(" @("!D969I;F5?;65T:&]D
#II;G-T86YC92PF1FER
M<W1);G-T86YC94-A;&PI#0HK(” @(" @96YD#0HK(" @(&5N9 TR @(" -
M"BL@(" @<')I=F%T90T
R @(" -“BL@(” @9&5F(&EN:71I86QI>F5?8V]P
2AO<FEG0T**R @(" @('-U<&5R#0HK(" @(" @4VEN9VQE=&]N0VQA<W–
M971H;V1S+F5X=&5N9&5D
’-E;&8I#0HK(" @(&5N9 TR @(" @( TR @
M(“!D968@:6YH97)I=&5D*'-U8E]K;&%S<RD-“BL@(” @(”!S=7!E<@TR @
M(" @(%-I;F=L971O;D-L87-S365T:&]D'1E;F1E9"AS=6)?:VQA<W,I
M#0HK(" @(&5N9 T
R @(" -“BL@(” @9&5F(%]L;V%D*‘-T<BD@#0HK(" @
M(" @:6YS=&%N8V4@#0HK(" @(&5N9 TR @96YD#0HK(" -"BL@( TR @
M<’)I=F%T90TR @(R @97AT96YD:6YG(&%N(&]B:F5C=“!W:71H(%-I;F=L
M971O;B!I<R!A(&)A9”!I9&5A#0HK("!U;F1E9E]M971H;V0@.F5X=&5N9%]O
M8FIE8W0-"BL@( T
R @9&5F(&%P<&5N9%]F96%T=7)E<RAM;V0I#0HK(" @
M(“,@(&AE;’ @;W5T('!E;W!L92!C;W5N=&EN9R!O;B!T<F%N<VET:79E(&UI
&EN<PTR @(“!U;FQE<W,@;6]D+FEN<W1A;F-E7V]F/RA#;&%S<RD-“BL@
M(” @(”!R86ES92!4>7!E17)R;W(L(“));F-L=7-I;VX@;V8@=&AE($]/+5-I
M;F=L971O;B!M;V1U;&4@:6X@;6]D=6QE(”-[;6]D?2(-“BL@(” @96YD#0HK
M(" @('-U<&5R#0HK("!E;F0-"BL@( T
R @9&5F(&EN8VQU9&5D*&ML87-S
M0TR @("!S=7!E<@TR @(“!K;&%S<RYP<FEV871E7V-L87-S7VUE=&AO
M9” Z;F5W+#IA;&QO8V%T90TR @(“!K;&%S'1E;F0@4VEN9VQE=&]N
M0VQA<W–971H;V1S#0HK(” @(%-I;F=L971O;D-L87-S365T:&]D'1E
M;F1E9"AK;&%S<RD-"BL@(&5N9 T
V5N9 TR -"BL-"BL-"BMI9B!?7T9)
M3$5?7R ]/2 D, T
R,@5&AE(&)A<VEC(&%N9"!M;W-T(&EM<&]R=&%N="!E
&%M<&QE+@TPTV-L87-S(%-O;653:6YG;&5T;VY#;&%S<PT**R @:6YC
M;'5D92!3:6YG;&5T;VX-"BME;F0-"BL-"BMN=6T@/2 @3V)J96-T4W!A8V4N
M96%C:%]O8FIE8W0H4V]M95-I;F=L971O;D-L87-S
2![?0TW!U=',@(E1H
M97)E(&%R92 C>VYU;7T@;V8@4V]M95-I;F=L971O;D-L87-S(&EN<W1A;F-E
M<R(@#0HK#0HK82 ](%-O;653:6YG;&5T;VY#;&%S<RYI;G-T86YC90T
V(@
M/2!3;VUE4VEN9VQE=&]N0VQA<W,N:6YS=&%N8V4@(R!A(&%N9”!B(&%R92!S
M86UE(&]B:F5C= TW!U=',@(F)A<VEC('1E<W0@:7,@(WMA(#T](&)](@T*
M*PT
V)E9VEN#0HK(“!3;VUE4VEN9VQE=&]N0VQA<W,N;F5W#0HK<F5S8W5E
M(”!.;TUE=&AO9$5R<F]R(#T^(&UE<PTR @<‘5T<R!M97,-"BME;F0-“BL-
M"BL-“BMP=71S(”)<;E1H<F5A9&5D(&5X86UP;&4@=VET:”!E>&-E<‘1I;VXB
M#0HK)’-T9&]U=“YS>6YC/2!T<G5E#0HK#0HK8VQA<W,@1F]O(#P@4V]M95-I
M;F=L971O;D-L87-S#0HK(”! 871T96UP=’,@/2 P#0HK#0HK("!D968@:6YI
M=&EA;&EZ90T
R @(“! =F%L:60@/2!F86QS90TR @(“!S;&5E<“AR86YD
M*# N,2DI#0HK(” @(&EF(‘-E;&8N8VQA<W,N871T96UP=’,@/” S#0HK(" @
M(" @<F%I<V4@(")B;V]M(“T@:6YI=&EA;&EZ92!F86EL960@9F]R('1H<F5A
M9” C(WM4:')E860N8W5R<F5N=%LZ:5U](@T
R @(”!E;‘-E#0HK(" @(" @
M0’9A;&ED(#T@=’)U90TR @(" @(‘!U=’,@(GEE<R$@+2!I;FET:6%L:7IE
M('-U8V-C965D960@9F]R(‘1H<F5A9" C(WM4:’)E860N8W5R<F5N=%LZ:5U]
M(@T
R @(“!E;F0-“BL@(&5N<W5R90TR @("!S96QF+F-L87-S+F%T=&5M
M<'1S*ST@,0T
R @96YD#0HK(” -“BL@(&1E9B!V86QI9#-“BL@(” @0’9A
M;&ED#0HK(”!E;F0@( TV5N9 TR @#0HK8VQA<W,@/#P@1F]O#0HK(”!A
M=‘1R7V%C8V5S<V]R(#IA=‘1E;7!T<PTR @#0HK(“!D968@:6YS=&%N8VEA
M=&5?86QL#0HK(” @(%1H<F5A9"YC=7)R96YT+G!R:6]R:71Y(#T@,3 Q#0HK
M(" @('1H<G,]($%R<F%Y+FYE=R@Q,#$I('M:7P@( T
R @(" @(&-U<G(]
M(%1H<F5A9"YN97<@>R -“BL@(” @(" @(&)E9VEN#0HK(" @(" @(" @(’-L
M965P*’)A;F0H,“XQ2D-“BL@(” @(" @(" @5&AR96%D+F-U<G)E;G1;.FE=
M(#T@:0TR @(" @(" @("!I;G-T86YC90TR @(" @(" @<F5S8W5E(#T^
M(&UE<PTR @(" @(" @("!P=71S(&UE<PTR @(" @(" @96YD#0HK(" @
M(" @?0T**R @(" @(&-U<G(N<')I;W)I='D@/2!R86YD
#$P,2D-“BL@(” @
M(”!C=7)R#0HK(" @(‘T-“BL@(” @<‘5T<R B0F5F;W)E(‘1H97)E(&5X:7-T
M960@(WMN=6U](‘9A;&ED(“-[<V5L9GT@:6YS=&%N8V4H<RDB#0HK(” @(’-L
M965P(#,-“BL@(” @=&AR<RYE86-H(‘M=‘P@=“YJ;VEN('T-“BL@(” @<'5T
M<R B3F]W(‘1H97)E(&5X:7-T*’,I(”-[;G5M?2!V86QI9" C>W-E;&9](&EN
M<W1A;F-E*’,I(@TR @96YD#0HK(" -"BL@(&1E9B!N=6T-“BL@(” @8VYT
M(#T@, T
R @("!/8FIE8W13<&%C92YE86-H7V]B:F5C=“AS96QF2![?&]
M(&-N=“L],2!I9B!O+G9A;&ED/R!]#0HK(” @(&-N= TR @96YD#0HK(" -
M"BL@('!R:79A=&4-"BL@( T
R @9&5F(&EN:71I86QI>F5?8V]P>2AO<FEG
M
0TR @("!S=7!E<@TR @(”! 871T96UP=’,@/2 P#0HK("!E;F0-"BME
M;F0@( TPTPTT9O;RYI;G-T86YC:6%T95]A;&P-"BLC(‘)E<W5L=’,@
M:6X@<V]M971H:6YG(&QI:V4Z#0HK(R!"969O<F4@=&AE<F4@=V5R92 P('9A
M;&ED($9O;R!I;G-T86YC92AS*0T
R,@8F]O;2 M(&EN:71I86QI>F4@9F%I
M;&5D(&9O<B!T:’)E860@(S<X#0HK(R!B;V]M(“T@:6YI=&EA;&EZ92!F86EL
M960@9F]R('1H<F5A9” C.3,-“BLC(&)O;VT@+2!I;FET:6%L:7IE(&9A:6QE
M9”!F;W(@=&AR96%D(",X#0HK(R!Y97,@+2!I;FET:6%L:7IE(’-U8V-C965D
M960@9F]R(‘1H<F5A9" C,C<-“BLC($YO=R!T:&5R92!A<F4@,2!V86QI9”!&
M;V@:6YS=&%N8V4H<RD-“BLC($YO=R!T:&5R92!A<F4@,2!V86QI9”!&;V@
M:6YS=&%N8V4H<RD-"BL-"BL-“BMP=71S(”)<;DQE=’,@<V5E(&EF(&-L87-S
M(&QE=F5L(&-L;VYI;F<@<F5A;&QY(’=O<FMS(@TT)A>B ]($9O;RYC;&]N
M90T
T)A>BYI;G-T86YC:6%T95]A;&P-“BL-“BL-“BMP=71S(”)<;EQN(BPB
M0W5S=&]M:7IE9”!M87)S:&%L;&EN9R(-“BMC;&%S<R!!#0HK(”!I;F-L=61E
M(%-I;F=L971O;@TR @871T<E]A8V-E<W-O<B Z<&5R<VES="P@.F1I90T*
MR @9&5F(%]D=6UP&1E<'1H*0T
R @(” C('1H:7,@<W1R:7!S('1H92!
M9&EE(&EN9F]R;6%T:6]N(&9R;VT@=&AE(&EN<W1A;F-E#0HK(" @($UA<G-H
M86PN9’5M<"A <&5R<VES="QD97!T:"D-"BL@(&5N9 TV5N9 TPTV1E
M9B!!+E]L;V%D*'-T<BD-"BL@(&EN<W1A;F-E+G!E<G-I<W0@/2!-87)S:&%L
M+FQO860H<W1R*0T
R @:6YS=&%N8V4-"BME;F0-"BL-“BMA(#T@02YI;G-T
M86YC90TV$N<&5R<VES=" ](%LB<&5R<VES=")=#0HK82YD:64@/2 B9&EE
M(@T
V$N=&%I;G0-“BL-“BMS=&]R961?<W1A=&4@/2!-87)S:&%L+F1U;7 H
M82D-“BLC(&-H86YG92!S=&%T90TV$N<&5R<VES=" ](&YI; TV$N9&EE
M(#T@;FEL#0HK8B ]($UA<G-H86PN;&]A9"AS=&]R961?<W1A=&4I#0HK<”!A
M(#T](&(@(”,@(#T^('1R=64-“BMP(&$N<&5R<VES=” @(R @/3X@6R)P97)S
M:7-T(ET-“BMP(&$N9&EE(” @(” @(R @/3X@;FEL#0HK#0HK#0HK<'5T<R B
M7&Y<;E-I;F=L971O;B!W:71H(&]V97)R:61D96X@9&5F875L=” C:6YH97)I
M=&5D*"D@:&]O:R(-"BMC;&%S<R!5< TV5N9 TV1E9B!5<"YI;FAE<FET
M960H<W5B7VML87-S0T**R @<‘5T<R B(WMS=6)?:VQA<W-](’-U8F-L87-S
M97,@(WMS96QF?2(-"BME;F0-"BL-"BL-“BMC;&%S<R!-:61D;&4@/”!5< T

MR @:6YC;'5D92!3:6YG;&5T;VX-"BME;F0-"BL-"BMC;&%S<R!$;W=N(#P@
M36ED9&QE.R!E;F0-“BL-“BMP=71S(” B86YD(&)A<VEC(%PB1&]W;B!T97-T
M7”(@:7,@(WM$;W=N+FEN<W1A;F-E(#T]($1O=VXN:6YS=&%N8V5]7&X-“BM6
M87)I;W5S(&5X8V5P=&EO;G,B(” -"BL-“BMB96=I;@TR @;6]D=6QE($%-
M;V1U;&4-“BL@(” @:6YC;'5D92!3:6YG;&5T;VX-"BL@(&5N9 T
W)E<V-U
M92!4>7!E17)R;W(@/3X@;65S#0HK(”!P=71S(&UE<R @(ST^($EN8VQU<VEO
M;B!O9B!T:&4@3T\M4VEN9VQE=&]N(&UO9’5L92!I;B!M;V1U;&4@04UO9’5L
M90TV5N9 TPTV)E9VEN#0HK(" G85-T<FEN9R<N97AT96YD(%-I;F=L
M971O;@T
W)E<V-U92!.;TUE=&AO9$5R<F]R(#T^(&UE<PTR @<'5T<R!M
M97,@(",]/B!U;F1E9FEN960@;65T:&]D(&!E>'1E;F1?;V)J96-T)R!F;W(@
A4VEN9VQE=&]N.DUO9’5L90T
V5N9 TPTV5N9 T

`
end

Hi,

···

At Fri, 16 Jan 2004 07:46:39 +0900, Christoph wrote:

Just using Thread.critical. And seems close to your idea
excepting for it uses “instance” method rather than “new”.

Not accurate, it uses 3-state; before, during and after
creation, but I feel it should use mutex or something.

You probably always need a 3-state if you want a self
modifying first instance call (at least in some implicit way).

Here is a mutexy version of singleton.rb I wrote some time
ago - it is probably more robust then the current code but equally
obscure - sorry …

Due to the line ending codes, your patch contains whole files.
Following is a bit modified version.

Index: lib/singleton.rb

RCS file: /cvs/ruby/src/ruby/lib/singleton.rb,v
retrieving revision 1.21
diff -u -2 -p -d -r1.21 singleton.rb
— lib/singleton.rb 22 Aug 2003 08:09:58 -0000 1.21
+++ lib/singleton.rb 16 Jan 2004 01:26:06 -0000
@@ -12,5 +12,5 @@

a,b = Klass.instance, Klass.instance

a == b # => true

-# a.new # NoMethodError - new is private …
+# Klass.new # NoMethodError - new is private …

* ``The instance’’ is created at instanciation time, in other

@@ -31,7 +31,5 @@

Providing (or modifying) the class methods

-# * Klass.inherited(sub_klass) and Klass.clone() -
-# to ensure that the Singleton pattern is properly
-# inherited and cloned.
+# * Klass.inherited(sub_klass) and Klass.initialize_copy()

* Klass.instance() - returning ``the instance’'. After a

@@ -45,20 +43,12 @@

* Klass._load(str) - calling Klass.instance()

-# * Klass._instanciate?() - returning ``the instance’’ or
-# nil. This hook method puts a second (or nth) thread calling
-# Klass.instance() on a waiting loop. The return value
-# signifies the successful completion or premature termination
-# of the first, or more generally, current “instanciation thread”.
-#

The instance method of Singleton are

-# * clone and dup - raising TypeErrors to prevent cloning or duping
+# * clone and dup - raising TypeErrors to prevent cloning

-# * _dump(depth) - returning the empty string. Marshalling strips
-# by default all state information, e.g. instance variables and
-# taint state, from the instance''. Providing custom _load(str) -# and _dump(depth) hooks allows the (partially) resurrections of -# a previous state of the instance’'.

+# * _dump(depth) - returning the empty string, in other words
+# marshalling strips all state information. Providing custom
+# _load(str) and _dump(depth) hooks allows the (partially)
+# resurrections of a previous state of ``the instance’'.

@@ -82,60 +72,61 @@ end
class << Singleton

Method body of first instance call.

  • FirstInstanceCall = proc do
  • @instance takes on one of the following values

  • * nil - before and after a failed creation

  • * false - during creation

  • * sub_class instance - after a successful creation

  • the form makes up for the lack of returns in progs

  • Thread.critical = true
  • if @instance.nil?
  •  @__instance__  = false
    
  •  Thread.critical = false
    
  •  begin
    
  • FirstInstanceCall = proc do ||
  • critical, Thread.critical = Thread.critical, true
  • begin
  •  if instanciating = @__instance__.nil?
    
  •    @__instance__ = false
    
  •    Thread.critical = critical
       @__instance__ = new
    
  •  ensure
    
  •    if @__instance__
    
  •      class <<self
    
  •        remove_method :instance
    
  •        def instance; @__instance__ end
    
  •      end
    
  •    else
    
  •      @__instance__ = nil #  failed instance creation
    
  •    end
    
  •  elsif !@__instance__
    
  •    @__instanciating_queue__ << Thread.current
    
  •    Thread.stop
    
  •    Thread.critical = true
    
  •    retry
     end
    
  • elsif _instanciate?()
  •  Thread.critical = false    
    
  • else
  •  @__instance__  = false
    
  •  Thread.critical = false
    
  •  begin
    
  •    @__instance__ = new
    
  •  ensure
    
  •  @__instance__
    
  • ensure
  •  if instanciating
    
  •    Thread.critical= true
       if @__instance__
    
  •      class <<self
    
  •      class << self
           remove_method :instance
           def instance; @__instance__ end
         end
    
  •      remove_instance_variable(@__instanciating_queue__).each do |thr|
    
  •        thr.wakeup
    
  •      end
       else
         @__instance__ = nil
    
  •      if thr = @__instanciating_queue__.shift
    
  •        thr.wakeup
    
  •      end
       end
     end
    
  •  Thread.critical = critical
    
    end
  • @instance
    end

  • module SingletonClassMethods

  • properly clone the Singleton pattern - did you know

  • that duping doesn’t copy class methods?

  • def clone

  •  Singleton.__init__(super)
    
  • module SingletonClassMethods

  • def self.extended(klass)

  •  klass.instance_eval { 
    
  •    @__instance__ = nil
    
  •    @__instanciating_queue__ = [] 
    
  •  }
    
  •  class << klass
    
  •    define_method(:instance, FirstInstanceCall)
    
  •  end
    

    end

    private

  • ensure that the Singleton pattern is properly inherited

  • def initialize_copy(orig)
  •  super
    
  •  SingletonClassMethods.extended(self)
    
  • end
  • def inherited(sub_klass)
    super
  •  Singleton.__init__(sub_klass)
    
  •  SingletonClassMethods.extended(sub_klass)
    
    end

@@ -143,23 +134,6 @@ class << Singleton
instance
end

  • waiting-loop hook

  • def _instanciate?()

  •  while false.equal?(@__instance__)
    
  •    Thread.critical = false
    
  •    sleep(0.08)   # timeout
    
  •    Thread.critical = true
    
  •  end
    
  •  @__instance__
    
  • end
    end

  • def init(klass)

  • klass.instance_eval { @instance = nil }

  • class << klass

  •  define_method(:instance,FirstInstanceCall)
    
  • end

  • klass

  • end

    private
    @@ -177,7 +151,7 @@ class << Singleton
    def included(klass)
    super

  • klass.private_class_method :new, :allocate

  • klass.private_class_method :new,:allocate
    klass.extend SingletonClassMethods
  • Singleton.init(klass)
  • SingletonClassMethods.extended(klass)
    end
    end
    @@ -186,9 +160,4 @@ end

if FILE == $0

-def num_of_instances(klass)

  • “#{ObjectSpace.each_object(klass){}} #{klass} instance(s)”
    -end

The basic and most important example.

@@ -196,5 +165,7 @@ class SomeSingletonClass
include Singleton
end
-puts “There are #{num_of_instances(SomeSingletonClass)}”
+
+num = ObjectSpace.each_object(SomeSingletonClass) {}
+puts “There are #{num} of SomeSingletonClass instances”

a = SomeSingletonClass.instance
@@ -209,90 +180,81 @@ end

+puts “\nThreaded example with exception”
+$stdout.sync= true

-puts “\nThreaded example with exception and customized #_instanciate?() hook”; p
-Thread.abort_on_exception = false
+class Foo < SomeSingletonClass

  • @attempts = 0

-class Ups < SomeSingletonClass
def initialize

  • self.class.__sleep
  • puts “initialize called by thread ##{Thread.current[:i]}”
  • end
    -end

-class << Ups

  • def _instanciate?
  • @enter.push Thread.current[:i]
  • while false.equal?(@instance)
  •  Thread.critical = false
    
  •  sleep 0.08 
    
  •  Thread.critical = true
    
  • @valid = false
  • sleep(rand(0.1))
  • if self.class.attempts < 3
  •  raise  "boom - initialize failed for thread ##{Thread.current[:i]}"
    
  • else
  •  @valid = true
    
  •  puts "yes! - initialize succceeded for thread ##{Thread.current[:i]}"
    
    end
  • @leave.push Thread.current[:i]
  • @instance
  • ensure
  • self.class.attempts+= 1
    end
  • def __sleep
  • sleep(rand(0.08))
  • end
  • def valid?
  • @valid
  • end
    +end
  • def new
  • begin
  •  __sleep
    
  •  raise  "boom - thread ##{Thread.current[:i]} failed to create instance"
    
  • ensure
  •  # simple flip-flop
    
  •  class << self
    
  •    remove_method :new
    
  •  end
    
  • end
  • end
    +class << Foo
  • attr_accessor :attempts

    def instanciate_all

  • @enter =
  • @leave =
  • 1.upto(9) {|i|
  •  Thread.new { 
    
  • Thread.current.priority = 101
  • thrs= Array.new(101) {|i|
  •  curr= Thread.new { 
       begin
    
  •      sleep(rand(0.1))
         Thread.current[:i] = i
    
  •      __sleep
         instance
    
  •    rescue RuntimeError => mes
    
  •    rescue => mes
         puts mes
       end
     }
    
  •  curr.priority = rand(101)
    
  •  curr
    
    }
  • puts “Before there were #{num_of_instances(self)}”
  • puts “Before there existed #{num} valid #{self} instance(s)”
    sleep 3
  • puts “Now there is #{num_of_instances(self)}”
  • puts “#{@enter.join '; '} was the order of threads entering the waiting loop”
  • puts “#{@leave.join '; '} was the order of threads leaving the waiting loop”
  • thrs.each {|t| t.join }
  • puts “Now there exist(s) #{num} valid #{self} instance(s)”
    end
    -end
  • def num
  • cnt = 0
  • ObjectSpace.each_object(self) {|o| cnt+=1 if o.valid? }
  • cnt
  • end
  • private
  • def initialize_copy(orig)
  • super
  • @attempts = 0
  • end
    +end

-Ups.instanciate_all
-# results in message like
-# Before there were 0 Ups instance(s)
-# boom - thread #6 failed to create instance
-# initialize called by thread #3
-# Now there is 1 Ups instance(s)
-# 3; 2; 1; 8; 4; 7; 5 was the order of threads entering the waiting loop
-# 3; 2; 1; 7; 4; 8; 5 was the order of threads leaving the waiting loop
+Foo.instanciate_all
+# results in something like:
+# Before there were 0 valid Foo instance(s)
+# boom - initialize failed for thread #78
+# boom - initialize failed for thread #93
+# boom - initialize failed for thread #8
+# yes - initialize succceeded for thread #27
+# Now there are 1 valid Foo instance(s)
+# Now there are 1 valid Foo instance(s)

puts “\nLets see if class level cloning really works”
-Yup = Ups.clone
-def Yup.new

  • begin
  • __sleep
  • raise “boom - thread ##{Thread.current[:i]} failed to create instance”
  • ensure
  • simple flip-flop

  • class << self
  •  remove_method :new
    
  • end
  • end
    -end
    -Yup.instanciate_all
    +Baz = Foo.clone
    +Baz.instanciate_all


Nobu Nakada