[#48779] Ruby jobs — Phlip <phlip_cpp@...>

Rubies:

31 messages 2002/09/01

[#48886] cgi redirect — Tom Robinson <tom@...>

in perl, this is easy:

15 messages 2002/09/03

[#48917] New list: ruby-modules - for module developers... — Sean Chittenden <sean@...>

Howdy folks. I've put together a new list for ruby developers at

18 messages 2002/09/03

[#48978] option remember

Hi,

16 messages 2002/09/04

[#49042] Options for optimizing a large Ruby system — sera@... (Francis Hwang)

Hi everybody:

16 messages 2002/09/04

[#49107] RE: suggestions to the Ruby community — "Berger, Daniel" <djberge@...>

I've been following the documentation discussion with some interest. Some

35 messages 2002/09/05
[#49136] RE: suggestions to the Ruby community — " JamesBritt" <james@...> 2002/09/05

[#49294] OS-independent build of ruby — "reckless" <reckless2k@...>

Hi,

42 messages 2002/09/06
[#49318] Re: OS-independent build of ruby — ptkwt@...1.aracnet.com (Phil Tomson) 2002/09/06

In article <alali7$cth$01$1@news.t-online.com>,

[#49450] JRuby (was Re: OS-independent build of ruby) — Austin Ziegler <austin@...> 2002/09/08

JRuby exists ...

[#49297] Larry Wall's comments on Ruby — ptkwt@...1.aracnet.com (Phil Tomson)

http://interviews.slashdot.org/article.pl?sid=02/09/06/1343222&mode=thread&tid=145

29 messages 2002/09/06

[#49301] Re: Larry Wall's comments on Ruby — Andrew Hunt <andy@...>

61 messages 2002/09/06
[#49372] Re: Larry Wall's comments on Ruby — Reimer Behrends <behrends@...> 2002/09/07

Patrick May (patrick-may@monmouth.com) wrote:

[#49446] Re: Larry Wall's comments on Ruby — Austin Ziegler <austin@...> 2002/09/08

On Sat, 7 Sep 2002 14:21:22 +0900, Reimer Behrends wrote:

[#49333] Re: Larry Wall's comments on Ruby — Andrew Hunt <andy@...>

>yeah and as I said, depending on your background , Ruby is just as full

20 messages 2002/09/06

[#49627] Re: Larry Wall's comments on Ruby — "Marcin 'Qrczak' Kowalczyk" <qrczak@...>

Mon, 9 Sep 2002 14:26:37 +0900, Wirianto Djunaidi <ryo_saeba_009@yahoo.com> pisze:

83 messages 2002/09/09
[#49658] Re: Larry Wall's comments on Ruby — "Christoph" <chr_news@...> 2002/09/10

"Yukihiro Matsumoto" wrote

[#49707] Re: Larry Wall's comments on Ruby — David.Stagner@...

I think Gavin is right... we don't "add" strings, we concatenate them.

16 messages 2002/09/10

[#49766] RubyInline 1.0.4 Released! (fwd) — Pat Eyler <pate@...>

Woohoo! another cool new toy to play with!

34 messages 2002/09/10
[#49965] Re: Windows XP : RubyInline 1.0.4 Released! (fwd) — "Park Heesob" <phasis@...> 2002/09/12

Hi,

[#49787] call for commentary: review of Ruby for a magazine (long, sorry!) — Rick Wayne <fewayne@...>

hello again folks,

30 messages 2002/09/10

[#49849] private variables — ts <decoux@...>

81 messages 2002/09/11
[#50348] Re: private variables — William Djaja Tjokroaminata <billtj@...> 2002/09/16

Well, will these localized/private variables make it into the next Ruby

[#49988] not grasping the method overloading/multi-dispatch thing — dblack@...

Hello --

58 messages 2002/09/12
[#49990] Re: not grasping the method overloading/multi-dispatch thing — Friedrich Dominicus <frido@...> 2002/09/12

dblack@candle.superlink.net writes:

[#50040] Re: not grasping the method overloading/multi-dispatch thing — ptkwt@...1.aracnet.com (Phil Tomson) 2002/09/12

In article <3D80AD8D.27388.FBF0F18@localhost>,

[#49992] Re: not grasping the method overloading/multi-dispatch thing — dblack@... 2002/09/12

Hi --

[#50027] interesting Perl Journal move — Pat Eyler <pate@...>

The Perl Journal is being reborn yet again. This time, it will be an

21 messages 2002/09/12
[#50041] Re: interesting Perl Journal move — Jim Freeze <jim@...> 2002/09/12

On Fri, Sep 13, 2002 at 01:44:18AM +0900, Pat Eyler wrote:

[#50172] DbTalk 0.7 — Dalibor Sramek <dali@...>

I would like to announce a new release of my Ruby project DbTalk.

17 messages 2002/09/13

[#50224] MVC and OO Design? — jcb@... (MetalOne)

The Model View Controller Architecture has always had me a bit

18 messages 2002/09/14

[#50298] camelCaseTo_ruby_case.rb ?? — Thomas Sdergaard <tsondergaard@...>

Hi,

21 messages 2002/09/15
[#50304] Re: camelCaseTo_ruby_case.rb ?? — dblack@... 2002/09/16

Hello --

[#50312] Re: camelCaseTo_ruby_case.rb ?? — Joel VanderWerf <vjoel@...> 2002/09/16

[#50369] Why are parser tools rarely used in ruby? — "MikkelFJ" <mikkelfj-anti-spam@...>

Why is it that all the ruby source I find in the Ruby (windows) distribution

25 messages 2002/09/16

[#50374] Dependency "trees" - suggestions? — Massimiliano Mirra <list@...>

I'm struggling with building dependency "trees" for rpkg. What

15 messages 2002/09/16

[#50403] comments and continuing strings on the next line — Paul Brannan <pbrannan@...>

I have a tendency to write:

14 messages 2002/09/16

[#50466] Qt vs. FOX vs. ? (was Help on installing ruby-qt on windowsXP) — "Volkmann, Mark" <Mark.Volkmann@...>

> -----Original Message-----

16 messages 2002/09/17

[#50525] Matz, if you're reading, please scan this email — ser@... (Sean Russell)

I've found a problem with the Ruby interpreter, wherein the

23 messages 2002/09/18
[#51226] Re: Matz, if you're reading, please scan this email — Sean Chittenden <sean@...> 2002/09/24

> I've found a problem with the Ruby interpreter, wherein the

[#51281] Re: Matz, if you're reading, please scan this email — ts <decoux@...> 2002/09/25

>>>>> "S" == Sean Chittenden <sean@chittenden.org> writes:

[#51454] Re: Matz, if you're reading, please scan this email — Sean Chittenden <sean@...> 2002/09/26

> S> In the unit tests for libxml, I think I've pushed things to SEGV land

[#51592] Re: Matz, if you're reading, please scan this email — ts <decoux@...> 2002/09/27

>>>>> "S" == Sean Chittenden <sean@chittenden.org> writes:

[#51742] Re: Matz, if you're reading, please scan this email — Sean Chittenden <sean@...> 2002/09/28

> >>>>> "S" == Sean Chittenden <sean@chittenden.org> writes:

[#51748] Re: Matz, if you're reading, please scan this email — ts <decoux@...> 2002/09/28

>>>>> "S" == Sean Chittenden <sean@chittenden.org> writes:

[#51796] ruby bug in tight loops? (was: Re: Matz, if you're reading, please scan this email) — Sean Chittenden <sean@...> 2002/09/28

> S> :-/ You could be right, but, the IO context is created when reading

[#51825] Re: ruby bug in tight loops? (was: Re: Matz, if you're reading, please scan this email) — ts <decoux@...> 2002/09/29

>>>>> "S" == Sean Chittenden <sean@chittenden.org> writes:

[#51826] Re: ruby bug in tight loops? (was: Re: Matz, if you're reading, please scan this email) — Sean Chittenden <sean@...> 2002/09/29

> S> Good catch, I fixed this in the CVS version, however this is a

[#51831] Re: ruby bug in tight loops? (was: Re: Matz, if you're reading, please scan this email) — ts <decoux@...> 2002/09/29

>>>>> "S" == Sean Chittenden <sean@chittenden.org> writes:

[#50579] How to Efficiently Calculate the Pattern of Zeros and Ones? — William Djaja Tjokroaminata <billtj@...>

Hi,

11 messages 2002/09/18

[#50606] Python the new Lisp, what about Ruby then? — web2ed@... (Edward Wilson)

I've been reading that Python is the new lisp.

19 messages 2002/09/18
[#50614] Re: Python the new Lisp, what about Ruby then? — Tom Sawyer <transami@...> 2002/09/19

come on! python the new lisp? what's that suppose to mean? nothing

[#50629] RE: Python the new Lisp, what about Ruby then? — "Mike Campbell" <michael_s_campbell@...> 2002/09/19

> ruby though just may gain as great a heritage as lisp due to its highly

[#50652] Is better to subclass or to add methods to an existing class? — Vincent Foley <vinfoley@...>

I was discussing with a (Python) friend last night. I told him that one

31 messages 2002/09/19

[#50667] select and select — dblack@...

Hello --

99 messages 2002/09/19
[#50906] class documentation — "Mark Volkmann" <volkmann2@...> 2002/09/21

Is there a general concensus as to the best tool/format for documenting Ruby

[#50787] Re: select and select — Joel VanderWerf <vjoel@...> 2002/09/20

Yukihiro Matsumoto wrote:

[#50911] Re: select and select — matz@... (Yukihiro Matsumoto) 2002/09/21

Hi,

[#50912] Re: select and select — dblack@... 2002/09/21

Hi --

[#51168] Re: select and select — "Gavin Sinclair" <gsinclair@...> 2002/09/24

[#51184] Re: select and select — dblack@... 2002/09/24

Hi --

[#51196] Re: select and select — "Gavin Sinclair" <gsinclair@...> 2002/09/24

[#51199] Re: select and select — dblack@... 2002/09/24

Hi --

[#50732] don't understand cause of `sysread': Bad file descriptor (Errno::EBADF) — Robert McGovern <tarasis@...>

Was writting a script to poll an audiotron (www.audiotron.net) and

13 messages 2002/09/19

[#50762] Thoughts on improving usage of Regexp#match — "Hal E. Fulton" <hal9000@...>

Please feel free to point out obvious things

15 messages 2002/09/20

[#50850] Checking hash key's and values, with case insensitivity — khabibiuf@... (Khurram)

Hey all,

26 messages 2002/09/20

[#50867] Speed up suggestions — Tomas Brixi <tomas_brixi@...>

Hello,

18 messages 2002/09/20

[#50878] String interpolation at will? — "Hal E. Fulton" <hal9000@...>

Maybe I'm overlooking something obvious,

14 messages 2002/09/20
[#50880] RE: String interpolation at will? — Steve Tuckner <STUCKNER@...> 2002/09/20

Maybe this is too dangerous but

[#50958] are functions/methods "first class objects"? — David Garamond <davegaramond@...>

sorry this is a bit philosophical, but i just wonder whether ruby can be

17 messages 2002/09/22

[#50972] Re: Speed up suggestions — Tomas Brixi <tomas_brixi@...>

Thanks all for speedup tips.

22 messages 2002/09/23
[#50975] Re: Speed up suggestions — Ryan Davis <ryand@...> 2002/09/23

[#50983] Re: Speed up suggestions — Tomas Brixi <tomas_brixi@...> 2002/09/23

[#51156] adding overload to ruby — "Bulat Ziganshin" <bulatz@...>

Hello all and especially Matz,

285 messages 2002/09/24
[#51462] Re: adding overload to ruby — William Djaja Tjokroaminata <billtj@...> 2002/09/26

Why not designing a new language with a mix of typed variable and untyped

[#51371] Re: adding overload to ruby — "Justin Johnson" <justinj@...> 2002/09/26

[#51372] Re: adding overload to ruby — "Bulat Ziganshin" <bulatz@...> 2002/09/26

Hello Justin,

[#51375] Re: adding overload to ruby — ts <decoux@...> 2002/09/26

>>>>> "B" == Bulat Ziganshin <bulatz@integ.ru> writes:

[#51376] Re: adding overload to ruby — "Bulat Ziganshin" <bulatz@...> 2002/09/26

Hello ts,

[#51378] Re: adding overload to ruby — ts <decoux@...> 2002/09/26

>>>>> "B" == Bulat Ziganshin <bulatz@integ.ru> writes:

[#51382] Re: adding overload to ruby — "Bulat Ziganshin" <bulatz@...> 2002/09/26

Hello ts,

[#51384] Re: adding overload to ruby — dblack@... 2002/09/26

Hi --

[#51388] Re: adding overload to ruby — "Bulat Ziganshin" <bulatz@...> 2002/09/26

Hello dblack,

[#51391] Re: adding overload to ruby — dblack@... 2002/09/26

Hi --

[#51413] Re: adding overload to ruby — "Justin Johnson" <justinj@...> 2002/09/26

[#51542] Re: adding overload to ruby — "Bulat Ziganshin" <bulatz@...> 2002/09/27

Hello Justin,

[#51574] R (was: adding overload to ruby) — Nikodemus Siivola <tsiivola@...> 2002/09/27

[#51576] Re: R (was: adding overload to ruby) — "Bulat Ziganshin" <bulatz@...> 2002/09/27

Hello Nikodemus,

[#51591] Re: R (was: adding overload to ruby) — Nikodemus Siivola <tsiivola@...> 2002/09/27

[#51621] Re: R — William Djaja Tjokroaminata <billtj@...> 2002/09/27

Hi,

[#51741] Re: R — Nikodemus Siivola <tsiivola@...> 2002/09/28

[#51747] Re: R — William Djaja Tjokroaminata <billtj@...> 2002/09/28

Hi,

[#51918] Re: R — "Bulat Ziganshin" <bulatz@...> 2002/09/30

Hello William,

[#51923] Re: R — matz@... (Yukihiro Matsumoto) 2002/09/30

Hi,

[#51938] Re: R — "Bulat Ziganshin" <bulatz@...> 2002/09/30

Hello Yukihiro,

[#51949] Re: R — matz@... (Yukihiro Matsumoto) 2002/09/30

Hi,

[#51953] Re: R — "Bulat Ziganshin" <bulatz@...> 2002/09/30

Hello Yukihiro,

[#51752] Re: R — dblack@... 2002/09/28

Hi --

[#51755] Re: R — William Djaja Tjokroaminata <billtj@...> 2002/09/28

Oh yes, in fact, this is one of our selling points, right? We show the

[#51593] RE: R (was: adding overload to ruby) — "Christian Boos" <cboos@...> 2002/09/27

Did you have a look at http://merd.net :

[#51467] Re: adding overload to ruby — <bbense+comp.lang.ruby.Sep.26.02@...> 2002/09/26

-----BEGIN PGP SIGNED MESSAGE-----

[#51185] Object-Oriented struct Model in C — William Djaja Tjokroaminata <billtj@...>

Hi,

20 messages 2002/09/24

[#51389] Is Ruby's grammar LL(k)? — Mauricio =?unknown-8bit?Q?Fern=E1ndez?= <batsman.geo@...>

16 messages 2002/09/26

[#51444] Ruby/Tk or mod_ruby or what ?? — GBanschbach@...

Dear All,

16 messages 2002/09/26

[#51486] Ruby - common pitfalls? — Rudolf Polzer <AntiATField_adsgohere@...>

Is there a list of common pitfalls beginners in this language should

32 messages 2002/09/26

[#51530] Where Is Method Call Precedence? — William Djaja Tjokroaminata <billtj@...>

Hi,

40 messages 2002/09/27

[#51639] RE: REXML namespace support — "Volkmann, Mark" <Mark.Volkmann@...>

In my case I'm given a string which is a namespace prefix and I want to

14 messages 2002/09/27

[#51809] thoughts on typelessness — dblack@...

Hi --

136 messages 2002/09/29
[#52055] Re: thoughts on typelessness — Bryan Murphy <bryan@...> 2002/10/01

Gavin Sinclair wrote:

[#52059] Re: thoughts on typelessness — Chris Gehlker <canyonrat@...> 2002/10/01

[#52062] Re: thoughts on typelessness — Bryan Murphy <bryan@...> 2002/10/01

Chris Gehlker wrote:

[#52081] Re: thoughts on typelessness — Chris Gehlker <canyonrat@...> 2002/10/01

[#52147] Re: thoughts on typelessness — William Djaja Tjokroaminata <billtj@...> 2002/10/01

Hi Dave,

[#52150] Re: thoughts on typelessness — Dave Thomas <Dave@...> 2002/10/01

William Djaja Tjokroaminata <billtj@y.glue.umd.edu> writes:

[#52151] Re: thoughts on typelessness — GOTO Kentaro <gotoken@...> 2002/10/01

At Wed, 2 Oct 2002 01:37:46 +0900,

[#52154] Re: thoughts on typelessness — Paul Brannan <pbrannan@...> 2002/10/01

On Wed, Oct 02, 2002 at 02:11:24AM +0900, GOTO Kentaro wrote:

[#51810] Re: thoughts on typelessness — William Djaja Tjokroaminata <billtj@...> 2002/09/29

Hi David,

[#51877] Re: thoughts on typelessness — Chris Gehlker <canyonrat@...> 2002/09/29

[#51818] announce@ == less email (FAQ item?) — Ryan Davis <ryand-ruby@...>

ZenTest and ZenWeb were just released. I announced these to several

40 messages 2002/09/29

[#51974] Things That Newcomers to Ruby Should Know — William Djaja Tjokroaminata <billtj@...>

Things That Newcomers to Ruby Should Know

37 messages 2002/09/30
[#52128] Re: Things That Newcomers to Ruby Should Know — William Djaja Tjokroaminata <billtj@...> 2002/10/01

Thanks, Gabriele. I will try to incorporate your input. The "0 is

[#52965] Re: Things That Newcomers to Ruby Should Know — "Kontra, Gergely" <kgergely@...> 2002/10/11

>> - the ||= operator exists :-)

[#52970] Re: Things That Newcomers to Ruby Should Know — William Djaja Tjokroaminata <billtj@...> 2002/10/11

Hi,

[#52971] Re: Things That Newcomers to Ruby Should Know — dblack@... 2002/10/11

Hi --

Re: private variables

From: ts <decoux@...>
Date: 2002-09-11 17:25:58 UTC
List: ruby-talk #49882
>>>>> "Y" == Yukihiro Matsumoto <matz@ruby-lang.org> writes:

Y> Do you mean you've implemented private instance variable, even if it's
Y> incomplete?  If so, show me the code please.

 Well, here a quick diff (*WARNING* old 1.6.7 : you can see it with
 NODE_CVASGN)

 To understand what it do

pigeon% cat b.rb
#!./ruby
class A
   def initialize
      @a = 12
      @_m = [1,2]
   end
end

class B < A
   def initialize
      @_m = [2,4]
      @_n = 6
      super
   end
end

Marshal.dump(B.new, File.new("aa", "w"))
pigeon% 

pigeon% b.rb
pigeon% 

pigeon% cat c.rb
#!/usr/bin/ruby
class A
end
class B < A
   def b
      puts "a = #{@a.inspect} - _m = #{@_m.inspect} - _n = #{@_n.inspect}"
   end
end

Marshal.load(IO.readlines("aa", nil)[0]).b
pigeon%

pigeon% c.rb
a = 12 - _m = {B=>[2, 4], A=>[1, 2]} - _n = {B=>6}
pigeon% 


 Now the problems :

  1) you need to have 2 hash access for a private variable, rather than one
     for a public variable

  2) I use

#define ID_PRIVATE 0x07

  which is used for ID_JUNK in 1.7.*

 For 1.7 I see only a possibility

#define ID_JUNK 0x00
#define ID_PRIVATE 0x07

 but this means that *all* bits are used and it will not possible to add
 new types after this


Guy Decoux


diff -u ruby-1.6.7/env.h ruby-1.6.m/env.h
--- ruby-1.6.7/env.h	2001-03-21 09:04:11.000000000 +0100
+++ ruby-1.6.m/env.h	2002-09-07 15:55:19.000000000 +0200
@@ -20,6 +20,7 @@
     ID last_func;
     VALUE last_class;
     VALUE cbase;
+    VALUE curr_class;
     struct FRAME *prev;
     struct FRAME *tmp;
     char *file;
diff -u ruby-1.6.7/eval.c ruby-1.6.m/eval.c
--- ruby-1.6.7/eval.c	2002-02-27 05:50:29.000000000 +0100
+++ ruby-1.6.m/eval.c	2002-09-11 14:17:29.000000000 +0200
@@ -110,6 +110,8 @@
 static VALUE rb_cUnboundMethod;
 static VALUE umethod_bind _((VALUE, VALUE));
 static VALUE rb_mod_define_method _((int, VALUE*, VALUE));
+static VALUE remove_private_variable __((VALUE, VALUE));
+static VALUE rb_current_class __((void));
 
 static int scope_vmode;
 #define SCOPE_PUBLIC    0
@@ -500,18 +502,19 @@
 static struct FRAME *top_frame;
 static struct SCOPE *top_scope;
 
-#define PUSH_FRAME() {			\
-    struct FRAME _frame;		\
-    _frame.prev = ruby_frame;		\
-    _frame.tmp  = 0;			\
-    _frame.file = ruby_sourcefile;	\
-    _frame.line = ruby_sourceline;	\
-    _frame.iter = ruby_iter->iter;	\
-    _frame.cbase = ruby_frame->cbase;	\
-    _frame.argc = 0;			\
-    _frame.argv = 0;			\
-    _frame.flags = FRAME_ALLOCA;	\
-    ruby_frame = &_frame;		\
+#define PUSH_FRAME() {				\
+    struct FRAME _frame;			\
+    _frame.prev = ruby_frame;			\
+    _frame.tmp  = 0;				\
+    _frame.file = ruby_sourcefile;		\
+    _frame.line = ruby_sourceline;		\
+    _frame.iter = ruby_iter->iter;		\
+    _frame.cbase = ruby_frame->cbase;		\
+    _frame.curr_class = ruby_frame->curr_class;	\
+    _frame.argc = 0;				\
+    _frame.argv = 0;				\
+    _frame.flags = FRAME_ALLOCA;		\
+    ruby_frame = &_frame;
 
 #define POP_FRAME()  			\
     ruby_sourcefile = _frame.file;	\
@@ -1026,6 +1029,7 @@
 	rb_call_inits();
 	ruby_class = rb_cObject;
 	ruby_frame->self = ruby_top_self;
+	ruby_frame->curr_class = rb_cObject;
 	top_cref = rb_node_newnode(NODE_CREF,rb_cObject,0,0);
 	ruby_cref = top_cref;
 	ruby_frame->cbase = (VALUE)ruby_cref;
@@ -1266,6 +1270,7 @@
     ruby_top_self = rb_obj_clone(ruby_top_self);
     rb_extend_object(ruby_top_self, ruby_wrapper);
     PUSH_FRAME();
+    ruby_frame->curr_class = ruby_class;
     ruby_frame->last_func = 0;
     ruby_frame->last_class = 0;
     ruby_frame->self = self;
@@ -2708,7 +2713,12 @@
 
       case NODE_IASGN:
 	result = rb_eval(self, node->nd_value);
-	rb_ivar_set(self, node->nd_vid, result);
+	if (rb_is_instance_id(node->nd_vid)) {
+	    rb_ivar_set(self, node->nd_vid, result);
+	}
+	else {
+	    rb_pvar_set(self, rb_current_class(), node->nd_vid, result);
+	}
 	break;
 
       case NODE_CDECL:
@@ -2732,7 +2742,11 @@
 
       case NODE_CVASGN:
 	result = rb_eval(self, node->nd_value);
-	rb_cvar_set(ruby_cbase, node->nd_vid, result);
+	if (!FL_TEST(ruby_cbase, FL_SINGLETON)) {
+	    rb_cvar_set(ruby_cbase, node->nd_vid, result);
+	    break;
+	}
+	rb_cvar_set(rb_iv_get(ruby_cbase, "__attached__"), node->nd_vid, result);
 	break;
 
       case NODE_LVAR:
@@ -2751,7 +2765,12 @@
 	break;
 
       case NODE_IVAR:
-	result = rb_ivar_get(self, node->nd_vid);
+        if (rb_is_instance_id(node->nd_vid)) {
+	    result = rb_ivar_get(self, node->nd_vid);
+	}
+	else {
+	    result = rb_pvar_get(self, rb_current_class(), node->nd_vid);
+	}
 	break;
 
       case NODE_CONST:
@@ -2941,7 +2960,13 @@
 	if (ruby_frame->argc != 1)
 	    rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",
 		     ruby_frame->argc);
-	result = rb_ivar_set(self, node->nd_vid, ruby_frame->argv[0]);
+        if (rb_is_instance_id(node->nd_vid)) {
+	    result = rb_ivar_set(self, node->nd_vid, ruby_frame->argv[0]);
+	}
+	else {
+	    result = rb_pvar_set(self, rb_current_class(), node->nd_vid,
+				 ruby_frame->argv[0]);
+	}
 	break;
 
       case NODE_DEFN:
@@ -3242,6 +3267,8 @@
     PUSH_SCOPE();
     PUSH_VARS();
 
+    ruby_frame->curr_class = ruby_class;
+
     if (node->nd_tbl) {
 	VALUE *vars = TMP_ALLOC(node->nd_tbl[0]+1);
 	*vars++ = (VALUE)node;
@@ -3570,6 +3597,7 @@
 	ruby_dyna_vars = block->dyna_vars;
     }
     ruby_class = klass?klass:block->klass;
+    ruby_frame->curr_class = ruby_class;
     if (!klass) self = block->self;
     node = block->body;
 
@@ -3826,7 +3854,11 @@
 	break;
 
       case NODE_CVASGN:
-	rb_cvar_set(ruby_cbase, lhs->nd_vid, val);
+	if (!FL_TEST(ruby_cbase, FL_SINGLETON)) {
+	    rb_cvar_set(ruby_cbase, lhs->nd_vid, val);
+	    break;
+	}
+	rb_cvar_set(rb_iv_get(ruby_cbase, "__attached__"), lhs->nd_vid, val);
 	break;
 
       case NODE_MASGN:
@@ -4362,6 +4394,9 @@
     ruby_frame->self = recv;
     ruby_frame->argc = argc;
     ruby_frame->argv = argv;
+    if (nd_type(body) != NODE_CFUNC) {
+	ruby_frame->curr_class = klass;
+    }
 
     switch (nd_type(body)) {
       case NODE_CFUNC:
@@ -4902,6 +4937,7 @@
     if (TYPE(ruby_class) == T_ICLASS) {
 	ruby_class = RBASIC(ruby_class)->klass;
     }
+    ruby_frame->curr_class = ruby_class;
     PUSH_TAG(PROT_NONE);
     if ((state = EXEC_TAG()) == 0) {
 	NODE *node;
@@ -5043,6 +5079,7 @@
     ruby_frame->last_class = _frame.prev->last_class;
     ruby_frame->argc = _frame.prev->argc;
     ruby_frame->argv = _frame.prev->argv;
+    ruby_frame->curr_class = ruby_class;
     if (ruby_cbase != under) {
 	ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,under,0,ruby_frame->cbase);
     }
@@ -5248,6 +5285,7 @@
     ruby_frame->last_class = 0;
     ruby_frame->self = self;
     ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,ruby_class,0,0);
+    ruby_frame->curr_class = ruby_class;
     PUSH_SCOPE();
     /* default visibility is private at loading toplevel */
     SCOPE_SET(SCOPE_PRIVATE);
@@ -6005,6 +6043,8 @@
     rb_define_method(rb_mKernel, "send", rb_f_send, -1);
     rb_define_method(rb_mKernel, "__send__", rb_f_send, -1);
     rb_define_method(rb_mKernel, "instance_eval", rb_obj_instance_eval, -1);
+    rb_define_private_method(rb_mKernel, "remove_private_variable",
+			     remove_private_variable, 1);
 
     rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
     rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
@@ -9091,3 +9131,16 @@
 	tt = tt->prev;
     }
 }
+
+static VALUE
+rb_current_class()
+{
+    return ruby_frame->curr_class;
+}
+
+static VALUE
+remove_private_variable(obj, name)
+    VALUE obj, name;
+{
+    return rb_obj_remove_private_variable(obj, rb_current_class(), name);
+}
diff -u ruby-1.6.7/gc.c ruby-1.6.m/gc.c
--- ruby-1.6.7/gc.c	2002-02-13 10:02:15.000000000 +0100
+++ ruby-1.6.m/gc.c	2002-09-07 16:11:11.000000000 +0200
@@ -911,6 +911,7 @@
 {
     mark_locations_array(frame->argv, frame->argc);
     rb_gc_mark(frame->cbase);
+    rb_gc_mark(frame->curr_class);
 }
 
 #ifdef __GNUC__
diff -u ruby-1.6.7/intern.h ruby-1.6.m/intern.h
--- ruby-1.6.7/intern.h	2002-02-27 05:50:30.000000000 +0100
+++ ruby-1.6.m/intern.h	2002-09-11 12:12:50.000000000 +0200
@@ -267,6 +267,7 @@
 void rb_parser_while_loop _((int, int));
 int rb_is_const_id _((ID));
 int rb_is_instance_id _((ID));
+int rb_is_private_id _((ID));
 int rb_is_class_id _((ID));
 VALUE rb_backref_get _((void));
 void rb_backref_set _((VALUE));
@@ -370,6 +371,11 @@
 void rb_mark_generic_ivar _((VALUE));
 void rb_mark_generic_ivar_tbl _((void));
 void rb_free_generic_ivar _((VALUE));
+VALUE rb_pvar_get _((VALUE, VALUE, ID));
+VALUE rb_pvar_set _((VALUE, VALUE, ID, VALUE));
+VALUE rb_pvar_defined _((VALUE, VALUE, ID));
+VALUE rb_obj_private_variables _((VALUE, VALUE));
+VALUE rb_obj_remove_private_variable _((VALUE, VALUE, VALUE));
 VALUE rb_ivar_get _((VALUE, ID));
 VALUE rb_ivar_set _((VALUE, ID, VALUE));
 VALUE rb_ivar_defined _((VALUE, ID));
diff -u ruby-1.6.7/marshal.c ruby-1.6.m/marshal.c
--- ruby-1.6.7/marshal.c	2002-02-28 07:52:47.000000000 +0100
+++ ruby-1.6.m/marshal.c	2002-09-08 13:50:33.000000000 +0200
@@ -755,19 +755,41 @@
     return v;
 }
 
+struct obj_id {
+    VALUE obj;
+    ID id;
+};
+
+static VALUE
+r_i_pvar(ary, st)
+    VALUE ary;
+    struct obj_id *st;
+{
+    rb_pvar_set(st->obj, RARRAY(ary)->ptr[0], st->id, RARRAY(ary)->ptr[1]);
+    return Qnil;
+}
+
 static void
 r_ivar(obj, arg)
     VALUE obj;
     struct load_arg *arg;
 {
     long len;
+    struct obj_id st;
 
     len = r_long(arg);
     if (len > 0) {
 	while (len--) {
 	    ID id = r_symbol(arg);
 	    VALUE val = r_object(arg);
-	    rb_ivar_set(obj, id, val);
+	    if (rb_is_private_id(id)) {
+		st.obj = obj;
+		st.id = id;
+		rb_iterate(rb_each, val, r_i_pvar, (VALUE)&st);
+	    }
+	    else {
+		rb_ivar_set(obj, id, val);
+	    }
 	}
     }
 }
diff -u ruby-1.6.7/object.c ruby-1.6.m/object.c
--- ruby-1.6.7/object.c	2002-02-04 09:09:10.000000000 +0100
+++ ruby-1.6.m/object.c	2002-09-11 12:14:15.000000000 +0200
@@ -1165,7 +1165,7 @@
     rb_define_method(rb_mKernel, "instance_variables", rb_obj_instance_variables, 0);
     rb_define_private_method(rb_mKernel, "remove_instance_variable",
 			     rb_obj_remove_instance_variable, 1);
-
+    rb_define_method(rb_mKernel, "private_variables", rb_obj_private_variables, 1);
     rb_define_method(rb_mKernel, "instance_of?", rb_obj_is_instance_of, 1);
     rb_define_method(rb_mKernel, "kind_of?", rb_obj_is_kind_of, 1);
     rb_define_method(rb_mKernel, "is_a?", rb_obj_is_kind_of, 1);
diff -u ruby-1.6.7/parse.y ruby-1.6.m/parse.y
--- ruby-1.6.7/parse.y	2002-02-20 05:28:51.000000000 +0100
+++ ruby-1.6.m/parse.y	2002-09-08 12:25:58.000000000 +0200
@@ -22,12 +22,14 @@
 
 #define ID_SCOPE_SHIFT 3
 #define ID_SCOPE_MASK 0x07
+
 #define ID_LOCAL    0x01
 #define ID_INSTANCE 0x02
 #define ID_GLOBAL   0x03
 #define ID_ATTRSET  0x04
 #define ID_CONST    0x05
 #define ID_CLASS    0x06
+#define ID_PRIVATE  0x07
 
 #define is_notop_id(id) ((id)>LAST_TOKEN)
 #define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL)
@@ -36,6 +38,7 @@
 #define is_attrset_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET)
 #define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST)
 #define is_class_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CLASS)
+#define is_private_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_PRIVATE)
 
 NODE *ruby_eval_tree_begin = 0;
 NODE *ruby_eval_tree = 0;
@@ -673,7 +676,7 @@
 			    if ($2 == tOROP) {
 				$<node>3->nd_value = $4;
 				$$ = NEW_OP_ASGN_OR(gettable($1), $<node>3);
-				if (is_instance_id($1)) {
+				if (is_instance_id($1) || is_private_id($1)) {
 				    $$->nd_aid = $1;
 				}
 			    }
@@ -4182,7 +4185,7 @@
     else if (is_global_id(id)) {
 	return NEW_GVAR(id);
     }
-    else if (is_instance_id(id)) {
+    else if (is_instance_id(id) || is_private_id(id)) {
 	return NEW_IVAR(id);
     }
     else if (is_const_id(id)) {
@@ -4237,7 +4240,7 @@
     else if (is_global_id(id)) {
 	return NEW_GASGN(id, val);
     }
-    else if (is_instance_id(id)) {
+    else if (is_instance_id(id) || is_private_id(id)) {
 	return NEW_IASGN(id, val);
     }
     else if (is_const_id(id)) {
@@ -4955,6 +4958,8 @@
       case '@':
 	if (name[1] == '@')
 	    id |= ID_CLASS;
+	else if (name[1] == '_')
+	    id |= ID_PRIVATE;
 	else
 	    id |= ID_INSTANCE;
 	break;
@@ -5065,6 +5070,14 @@
     return Qfalse;
 }
 
+int
+rb_is_private_id(id)
+    ID id;
+{
+    if (is_private_id(id)) return Qtrue;
+    return Qfalse;
+}
+
 static void
 special_local_set(c, val)
     char c;
diff -u ruby-1.6.7/ruby.h ruby-1.6.m/ruby.h
--- ruby-1.6.7/ruby.h	2002-02-26 14:08:17.000000000 +0100
+++ ruby-1.6.m/ruby.h	2002-09-08 14:00:04.000000000 +0200
@@ -466,6 +466,8 @@
 VALUE rb_gv_get _((const char*));
 VALUE rb_iv_get _((VALUE, const char*));
 VALUE rb_iv_set _((VALUE, const char*, VALUE));
+VALUE rb_pv_get _((VALUE, VALUE, const char*));
+VALUE rb_pv_set _((VALUE, VALUE, const char*, VALUE));
 
 VALUE rb_equal _((VALUE,VALUE));
 
diff -u ruby-1.6.7/variable.c ruby-1.6.m/variable.c
--- ruby-1.6.7/variable.c	2002-02-19 05:48:04.000000000 +0100
+++ ruby-1.6.m/variable.c	2002-09-11 12:12:17.000000000 +0200
@@ -885,6 +885,7 @@
     VALUE clone, obj;
 {
     st_table *tbl;
+    VALUE val;
 
     if (!generic_iv_tbl) return;
     if (st_lookup(generic_iv_tbl, obj, &tbl)) {
@@ -892,6 +893,295 @@
     }
 }
 
+static void
+check_valid_class(klass)
+    VALUE klass;
+{
+    switch (TYPE(klass)) {
+    case T_CLASS:
+    case T_ICLASS:
+    case T_MODULE:
+    case T_TRUE:
+    case T_FALSE:
+    case T_NIL:
+	break;
+    default:
+	rb_raise(rb_eArgError, "expected a class object");
+    }
+}
+
+static VALUE
+private_ivar_get(obj, klass, id)
+    VALUE obj, klass;
+    ID id;
+{
+    st_table *tbl;
+    VALUE val;
+
+    if (!generic_iv_tbl) return Qnil;
+    if (!st_lookup(generic_iv_tbl, obj, &tbl)) return Qnil;
+    if (st_lookup(tbl, id, &val) && TYPE(val) == T_HASH &&
+	st_lookup(RHASH(val)->tbl, klass, &val)) {
+	return val;
+    }
+    return Qnil;
+}
+
+VALUE
+rb_pvar_get(obj, klass, id)
+    VALUE klass, obj;
+    ID id;
+{
+    VALUE val;
+
+    check_valid_class(klass);
+    if (!rb_is_private_id(id)) {
+	rb_raise(rb_eNameError, "`%s' is not a private variable",
+		 rb_id2name(id));
+    }
+    switch (TYPE(obj)) {
+      case T_OBJECT:
+      case T_CLASS:
+      case T_MODULE:
+	if (ROBJECT(obj)->iv_tbl && 
+	    st_lookup(ROBJECT(obj)->iv_tbl, id, &val) &&
+	    TYPE(val) == T_HASH && st_lookup(RHASH(val)->tbl, klass, &val)) {
+	    return val;
+	}
+	break;
+      default:
+	if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
+	    return private_ivar_get(obj, klass, id);
+	}
+	break;
+    }
+    if (ruby_verbose) {
+	rb_warning("private variable %s not initialized", rb_id2name(id));
+    }
+    return Qnil;
+}
+
+static void
+private_ivar_set(obj, klass, id, val)
+    VALUE obj, klass;
+    ID id;
+    VALUE val;
+{
+    st_table *tbl;
+    VALUE stbl;
+
+    if (rb_special_const_p(obj)) {
+	special_generic_ivar = 1;
+    }
+    if (!generic_iv_tbl) {
+	generic_iv_tbl = st_init_numtable();
+    }
+
+    if (!st_lookup(generic_iv_tbl, obj, &tbl)) {
+	FL_SET(obj, FL_EXIVAR);
+	tbl = st_init_numtable();
+	st_add_direct(generic_iv_tbl, obj, tbl);
+    }
+    if (!st_lookup(tbl, id, &stbl)) {
+	stbl = rb_hash_new();
+	st_add_direct(tbl, id, stbl);
+    }
+    if (TYPE(stbl) != T_HASH) {
+	rb_raise(rb_eNameError, "`%s' is not a private variable",
+		 rb_id2name(id));
+    }
+    rb_hash_aset(stbl, klass, val);
+}
+ 
+VALUE
+rb_pvar_set(obj, klass, id, val)
+    VALUE klass, obj;
+    ID id;
+    VALUE val;
+{
+    VALUE stbl;
+
+    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
+	rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
+    if (OBJ_FROZEN(obj)) rb_error_frozen("object");
+
+    check_valid_class(klass);
+    if (!rb_is_private_id(id)) {
+	rb_raise(rb_eNameError, "`%s' is not a private variable",
+		 rb_id2name(id));
+    }
+    switch (TYPE(obj)) {
+      case T_OBJECT:
+      case T_CLASS:
+      case T_MODULE:
+	if (!ROBJECT(obj)->iv_tbl) ROBJECT(obj)->iv_tbl = st_init_numtable();
+	if (!st_lookup(ROBJECT(obj)->iv_tbl, id, &stbl)) {
+	    stbl = rb_hash_new();
+	    st_add_direct(ROBJECT(obj)->iv_tbl, id, stbl);
+	}
+	if (TYPE(stbl) != T_HASH) {
+	    rb_raise(rb_eNameError, "`%s' is not a private variable",
+		     rb_id2name(id));
+	}
+	rb_hash_aset(stbl, klass, val);
+	break;
+      default:
+	private_ivar_set(obj, id, val);
+	break;
+    }
+    return val;
+}
+
+static VALUE
+private_ivar_defined(obj, klass, id)
+    VALUE obj, klass;
+    ID id;
+{
+    st_table *tbl;
+    VALUE val;
+    
+    if (!generic_iv_tbl) return Qfalse;
+    if (st_lookup(generic_iv_tbl, obj, &tbl) &&	st_lookup(tbl, id, &val) &&
+	TYPE(val) == T_HASH && st_lookup(RHASH(val)->tbl, klass, 0)) {
+	return Qtrue;
+    }
+    return Qfalse;
+}
+
+VALUE
+rb_pvar_defined(obj, klass, id)
+    VALUE obj, klass;
+    ID id;
+{
+    VALUE stbl;
+
+    check_valid_class(klass);
+    if (!rb_is_private_id(id)) {
+	rb_raise(rb_eNameError, "`%s' is not a private variable",
+		 rb_id2name(id));
+    }
+    switch (TYPE(obj)) {
+      case T_OBJECT:
+      case T_CLASS:
+      case T_MODULE:
+	if (ROBJECT(obj)->iv_tbl && 
+	    st_lookup(ROBJECT(obj)->iv_tbl, id, &stbl) &&
+	    TYPE(stbl) == T_HASH && st_lookup(RHASH(stbl)->tbl, klass, 0))
+	    return Qtrue;
+	break;
+      default:
+	  if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
+	    return private_ivar_defined(obj, klass, id);
+	  }
+	break;
+    }
+    return Qfalse;
+}
+
+struct ary_class {
+    VALUE ary;
+    VALUE klass;
+};
+
+static int
+pvar_i(key, val, st)
+    ID key;
+    VALUE val;
+    struct ary_class *st;
+{
+    if (rb_is_private_id(key) && TYPE(val) == T_HASH &&
+	st_lookup(RHASH(val)->tbl, st->klass, 0)) {
+	rb_ary_push(st->ary, rb_str_new2(rb_id2name(key)));
+    }
+    return ST_CONTINUE;
+}
+
+VALUE
+rb_obj_private_variables(obj, klass)
+    VALUE obj, klass;
+{
+    VALUE ary;
+    struct ary_class st;
+
+    check_valid_class(klass);
+    ary = rb_ary_new();
+    switch (TYPE(obj)) {
+      case T_OBJECT:
+      case T_CLASS:
+      case T_MODULE:
+	if (ROBJECT(obj)->iv_tbl) {
+	    st.ary = ary;
+	    st.klass = klass;
+	    st_foreach(ROBJECT(obj)->iv_tbl, pvar_i, &st);
+	}
+	break;
+      default:
+	if (!generic_iv_tbl) break;
+	if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
+	    st_table *tbl;
+
+	    if (st_lookup(generic_iv_tbl, obj, &tbl)) {
+		st.ary = ary;
+		st.klass = klass;
+		st_foreach(tbl, pvar_i, &st);
+	    }
+	}
+	break;
+    }
+    return ary;
+}
+
+static VALUE
+generic_pvar_remove(obj, klass, id)
+    VALUE obj, klass;
+    ID id;
+{
+    st_table *tbl;
+    VALUE val, stbl;
+
+    if (!generic_iv_tbl) return Qnil;
+    if (!st_lookup(generic_iv_tbl, obj, &tbl)) return Qnil;
+    if (!st_lookup(tbl, id, &stbl)) return Qnil;
+    if (TYPE(stbl) != T_HASH) return Qnil;
+    val = RHASH(stbl)->ifnone;
+    st_delete(RHASH(stbl)->tbl, &klass, &val);
+    return val;
+}
+
+VALUE
+rb_obj_remove_private_variable(obj, klass, name)
+    VALUE obj, klass, name;
+{
+    VALUE val = Qnil;
+    ID id = rb_to_id(name);
+
+    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
+	rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
+    if (OBJ_FROZEN(obj)) rb_error_frozen("object");
+    if (!rb_is_private_id(id)) {
+	rb_raise(rb_eNameError, "`%s' is not a private variable",
+		 rb_id2name(id));
+    }
+    check_valid_class(klass);
+
+    switch (TYPE(obj)) {
+      case T_OBJECT:
+      case T_CLASS:
+      case T_MODULE:
+	if (ROBJECT(obj)->iv_tbl &&
+	    st_lookup(ROBJECT(obj)->iv_tbl, id, &val) &&
+	    TYPE(val) == T_HASH) {
+	    st_delete(RHASH(val)->tbl, &klass, &val);
+	}
+	break;
+      default:
+	if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
+	    return generic_pvar_remove(obj, klass, id);
+	break;
+    }
+    return val;
+}
+
 VALUE
 rb_ivar_get(obj, id)
     VALUE obj;
@@ -899,6 +1189,9 @@
 {
     VALUE val;
 
+    if (rb_is_private_id(id)) {
+	return rb_pvar_get(obj, 1, id);
+    }
     switch (TYPE(obj)) {
       case T_OBJECT:
       case T_CLASS:
@@ -926,6 +1219,9 @@
     if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
 	rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
     if (OBJ_FROZEN(obj)) rb_error_frozen("object");
+    if (rb_is_private_id(id)) {
+	return rb_pvar_set(obj, 1, id, val);
+    }
     switch (TYPE(obj)) {
       case T_OBJECT:
       case T_CLASS:
@@ -945,6 +1241,9 @@
     VALUE obj;
     ID id;
 {
+    if (rb_is_private_id(id)) {
+	return rb_pvar_defined(obj, 1, id);
+    }
     switch (TYPE(obj)) {
       case T_OBJECT:
       case T_CLASS:
@@ -1549,3 +1848,24 @@
 
     return rb_ivar_set(obj, id, val);
 }
+
+VALUE
+rb_pv_get(obj, klass, name)
+    VALUE obj, klass;
+    const char *name;
+{
+    ID id = rb_intern(name);
+
+    return rb_pvar_get(obj, klass, id);
+}
+
+VALUE
+rb_pv_set(obj, klass, name, val)
+    VALUE obj, klass;
+    const char *name;
+    VALUE val;
+{
+    ID id = rb_intern(name);
+
+    return rb_pvar_set(obj, klass, id, val);
+}

In This Thread