[#1649] Re: New Ruby projects — Yukihiro Matsumoto <matz@...>
The following message is a courtesy copy of an article
[#1672] Re: Ruby 1.4 stable manual bug? — Yukihiro Matsumoto <matz@...>
The following message is a courtesy copy of an article
[#1673] Re: Possible problem with ext/socket in 1.5.2 — itojun@...
[#1694] Conventions for our Ruby book — Dave Thomas <Dave@...>
[#1715] Install postgresql support — Ikhlasul Amal <amal@...>
Hi all,
Hi,
[#1786] Is this a bug? — Clemens Hintze <clemens.hintze@...>
(mailed & posted)
[#1814] Objects nested sometimes. — Hugh Sasse Staff Elec Eng <hgs@...>
I am attemptiong to write a package which consists of a workspace
[#1816] Ruby 1.5.3 under Tru64 (Alpha)? — Clemens Hintze <clemens.hintze@...>
Hi all,
Hi,
Yukihiro Matsumoto writes:
Hi,
Hi,
[#1834] enum examples? — Hugh Sasse Staff Elec Eng <hgs@...>
Has anyone any examplse of using the Enumerable module? I've had a
[#1844] Minor irritation, can't figure out how to patch it though! — Hugh Sasse Staff Elec Eng <hgs@...>
I was considering how difficult it would be to patch Ruby to accept
[#1889] [ruby-1.5.3] require / SAFE — ts <decoux@...>
[#1896] Ruby Syntax similar to other languages? — "David Douthitt" <DDouthitt@...>
From: Yukihiro Matsumoto <matz@netlab.co.jp>
[#1900] Enumerations and all that. — Hugh Sasse Staff Elec Eng <hgs@...>
Thank you to the people who responded to my questions about Enumerated
Hugh Sasse Staff Elec Eng <hgs@dmu.ac.uk> writes:
On 16 Mar 2000, Dave Thomas wrote:
[#1929] Re: Class Variables — "David Douthitt" <DDouthitt@...>
| "David Douthitt" <DDouthitt@cuna.com> writes:
[#1942] no Fixnum#new ? — Quinn Dunkan <quinn@...>
Ok, I can add methods to a built-in class well enough (yes I know about succ,
[#1989] English Ruby/Gtk Tutorial? — schneik@...
Hi,
[#2022] rb_global_entry — ts <decoux@...>
[#2036] Anonymous and Singleton Classes — B_DAVISON <Bob.Davison@...>
I am a Ruby newbie and having some problems getting my mind around certain
[#2069] Ruby/GTK+ question about imlib --> gdk-pixbug — schneik@...
[#2073] Re: eval.rb fails — "Dat Nguyen" <thucdat@...>
The doc is fine, this happens only if you try to execute 'until' block
On Wed, 22 Mar 2000, Dat Nguyen wrote:
[#2084] Scope violated by import via 'require'? — Clemens Hintze <c.hintze@...>
Hi,
[#2104] ARGF or $< — Hugh Sasse Staff Elec Eng <hgs@...>
Has anyone any examples of how to use ARGF or $< as I cannot find much
Hi.
[#2165] Ruby strict mode and stand-alone executables. — "Conrad Schneiker" <schneiker@...>
Some people want Ruby to have a strict compile mode.
[#2203] Re: parse bug in 1.5 — schneik@...
[#2212] Re: Ruby/Glade usage questions. — ts <decoux@...>
>>>>> "m" == mrilu <mrilu@ale.cx> writes:
[#2241] setter() for local variables — ts <decoux@...>
[#2256] Multiple assignment of pattern match results. — schneik@...
[#2267] Re: Ruby and Eiffel — h.fulton@...
[#2309] Question about attribute writers — Dave Thomas <Dave@...>
Clemens Hintze <c.hintze@gmx.net> writes:
[ruby-talk:02281]
> > On Tue, 28 Mar 2000, Andrew Hunt wrote:
> >
> > > Well, that brings up an interesting question. What do
> > > you think about implementing Design By Contract in a
> > > non-staticaly typed language such as Ruby? I've toyed around
> > > with several implementations of DBC in Ruby, and once Dave
> > > and I get a bit more of the Ruby book finished I'll look at
> > > it again.
> > >
> > > But would that be a usefull feature to have in Ruby?
> > Having looked at this a little, I can see it would be a good idea.
On Thu, 30 Mar 2000 h.fulton@att.net wrote:
> I am trying to implement the best system I can
> *without* changing the language spec...
Me too! I've thought about usefulness of invariants and method conditions
and tried to find imagine why they are more usefull than normal
assertions. I don't know. I guess since they are named a little bit
differently they could be used as a part of the documentation. And there I
can see their usefulness easily.
So after the the discussion on the list started I got more and more
excited. Then I decided to give it a try and try to create Design By
Contract -module.
Here you are, this is the first version:
module DBC
class DBCError < StandardError ; end
class DBCPreError < DBCError ; end
class DBCPostError < DBCError ; end
class DBCInvariantError < DBCError ; end
def pre
raise DBCPreError unless yield
end
def post(klass, method, invariant)
raise DBCPostError unless yield
if defined? invariant and
klass.public_instance_methods.include? method then
raise DBCInvariantError unless invariant()
end
end
end
And then testing code:
include DBC
class Foo
@a
def invariant
@a != 3
end
def initialize
@a = 0
end
def bar(b)
pre { b != 1 }
@a += b
print "@a = ", @a, "\n"
post( Foo, "bar", self) { @a != 2 }
end
end
for i in (0..4) do
print "\nTesting foo.bar(#{i})\n"
foo = Foo.new
begin
foo.bar(i)
rescue DBCPreError
print "DBCPreError happened as expected\n"
rescue DBCPostError
print "DBCPostError happened as expected\n"
rescue DBCInvariantError
print "DBCInvariantError happened as expected\n"
rescue Exception
print "Some unexpected error happened\n"
end
end
Produces:
Testing foo.bar(0)
@a = 0
Testing foo.bar(1)
DBCPreError happened as expected
Testing foo.bar(2)
@a = 2
DBCPostError happened as expected
Testing foo.bar(3)
@a = 3
DBCInvariantError happened as expected
Testing foo.bar(4)
@a = 4
> Of course, I am running into problems. But it
> remains to be seen whether these problems are
> insoluble, or just require more digging in the
> Ruby reference.
I was running into many many problems before this seemed to work or do
something in "right direction" :).
Now I list few:
- how it's possible to access something inside the class from other class?
Current version defines invariant, but that method is public so everybody
can call it. Making it private hides it from post too. I tried to use
instance variables, class variables etc., but this was the first one that
I managed to work. Just to give you some idea, at some point I had:
Invariant = proc { @a < 3 };
I thought attr, especially attr_reader could be for some help. I rejected
possibility to mix-in DBC, because then the same code would be in exactly
same form in every DBC-using class. What a waste of CPU at compiling, and
memory.
- how to check where we're coming?
I tried to use caller, but it's returning values are basically only for
printing. It returns some strings in weird format like "file.rb:25". I'd
like to have full (read) access to stack. See what was the method where we
came, the associated object, arguments etc.
Basically I'd like to change my code to say post-assertion without need to
"tediously" type calling instance, it's class and method. (Actually now I
noticed that we probably can drop class away, since we should be able to
say something like self.type at post-check.) How to get calling method
automatically? With stack access this should be no problem.
- how to recompile some code efficiently?
Here I would add some code for pre-execute, and post-execute hooks. Since
there is none, I considered to take method declaration and modify it and
then substitute the original code with modifications. At this point I
considered also to wrap function automagically:
class Foo
def bar
end
end
def foo_invariant
end
Foo.bar = DBC.check( proc { pretest }, proc {posttest}, foo_invariant )
This check routine replaces so that Foo's bar becomes
def Foo.bar
DBC.pre Foo
# original code
DBC.post Foo
end
I just couldn't produce it. Maybe somebody can help here (too!).
- btw it's tedious (to remember) to type semicolon to
class DBCError < StandardError ; end
- many more
It's just way too late for last efficient working day before hacking
weekend :).
the future is under construction