Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

No :<, :>, etc. methods for Array

6 views
Skip to first unread message

Brian F. Feldman

unread,
Jan 7, 2001, 12:53:35 AM1/7/01
to
So, why not include Comparable in Array by default? It shouldn't have any
bad side-effects, and it makes sense that if Array implements :<=>, it
should then include Comparable.

--
Brian Fundakowski Feldman \ FreeBSD: The Power to Serve! /
gr...@FreeBSD.org `------------------------------'


Yukihiro Matsumoto

unread,
Jan 7, 2001, 1:12:08 PM1/7/01
to
Hi,

In message "[ruby-talk:8774] No :<, :>, etc. methods for Array"


on 01/01/07, "Brian F. Feldman" <gr...@FreeBSD.org> writes:

|So, why not include Comparable in Array by default? It shouldn't have any
|bad side-effects, and it makes sense that if Array implements :<=>, it
|should then include Comparable.

Because arrays are not always comparable. `sort', `min', and `max' in
Enumerable are the best compromise I could made.

matz.

Brian F. Feldman

unread,
Jan 7, 2001, 2:17:34 PM1/7/01
to

So it's done to "discourage" people from doing it? E.g. currently the best
way to compare version numbers would be:

irb(main):003:0> ([1, 6, 2] <=> [1, 4, 3]) == 1
true

I also had a question if Array specifically could have a Array#sum method;
the behavior would be very simple and straightforward:

class Array
def sum
total = self[0] # defaults to nil
self[1..-1].each {|x| total += x}
total
end
end

It simplifies lots of things (especially mathematics) in Ruby to have it,
and I believe it's generally useful enough that it should probably be
standard. What do you think?

Brian F. Feldman

unread,
Jan 7, 2001, 2:45:31 PM1/7/01
to
got...@math.sci.hokudai.ac.jp (GOTO Kentaro) wrote:
> In message "[ruby-talk:8780] Re: No :<, :>, etc. methods for Array"

> on 01/01/08, "Brian F. Feldman" <gr...@FreeBSD.org> writes:
> >class Array
> > def sum
> > total = self[0] # defaults to nil
> > self[1..-1].each {|x| total += x}
> > total
> > end
> >end
> >
> >It simplifies lots of things (especially mathematics) in Ruby to have it,
> >and I believe it's generally useful enough that it should probably be
> >standard. What do you think?
>
> See:
> http://www.rubycentral.com/faq/rubyfaq-11.html#ss11.4
>
> `Enumerable#inject' is introduced there. That may be adopted if an
> apter method name is proposed.

Except that I don't really ever see the need for the inject functionality
itself. A general sum method wouldn't prevent an inject method from being
created, and I feel it's much more generally important (if it were in
Enumerable, it feels natural next to min and max).

I know you can define sum in terms of inject, but what is the point of
having inject if people are just going to use it to create sum?

GOTO Kentaro

unread,
Jan 7, 2001, 2:40:17 PM1/7/01
to
In message "[ruby-talk:8780] Re: No :<, :>, etc. methods for Array"

on 01/01/08, "Brian F. Feldman" <gr...@FreeBSD.org> writes:
>class Array
> def sum
> total = self[0] # defaults to nil
> self[1..-1].each {|x| total += x}
> total
> end
>end
>
>It simplifies lots of things (especially mathematics) in Ruby to have it,
>and I believe it's generally useful enough that it should probably be
>standard. What do you think?

See:
http://www.rubycentral.com/faq/rubyfaq-11.html#ss11.4

`Enumerable#inject' is introduced there. That may be adopted if an
apter method name is proposed.

-- Gotoken

Jean Michel

unread,
Jan 7, 2001, 4:13:03 PM1/7/01
to
In article <200101071944...@green.dyndns.org>,
Brian F. Feldman <gr...@FreeBSD.org> wrote:
....

>I know you can define sum in terms of inject, but what is the point of
>having inject if people are just going to use it to create sum?

It can also be used to create product (also very important), and, if the
definition is done the right way one also gets alternating sums (using
'-'). One can also get continued fractions, min and max of an array
(from min and max of 2 elements), intersection of a family of sets (with
'&'), etc...

Note that a direct call to inject has an advantage over sum: the
neutral element for the operation can be specified; so a call to

a.inject(0){|n, value| n + value}

works even for empty a (contrary to your proposed definition). Also

a.inject(""){|n, value| n + value}

does join for string arrays.

I learned the usefulness of inject while working with APL in the
seventies (yes, I am *that* old...) where it was called "reduce". Thus,
I also propose 'reduce' as a name for inject.

While I am at it, I would like to mention something I wish for ruby: in
APL or in more modern languages with a functional flavour, you can just
write '+' for the block {|a,b| a+b}. I wish something similar was
possible in ruby so one could just write

a.reduce(0,+)

instead of the above -- or perhaps more realistically:

a.reduce(0,:+)

It would also have the advantage to be able to easily (hum, I don't know
about that, I have not yet learned ruby internals) implement kernel
optimizations of the above call when the argument '+' is itself a kernel
function (would not you dream to be able to write ruby programs which
run faster than fortran, as was possible in APL by using similar
tricks?).

Best regards,
Jean MICHEL

David Alan Black

unread,
Jan 7, 2001, 4:13:22 PM1/7/01
to
Hello --

On Mon, 8 Jan 2001, Brian F. Feldman wrote:

> Except that I don't really ever see the need for the inject functionality
> itself. A general sum method wouldn't prevent an inject method from being
> created, and I feel it's much more generally important (if it were in
> Enumerable, it feels natural next to min and max).
>
> I know you can define sum in terms of inject, but what is the point of
> having inject if people are just going to use it to create sum?

You're assuming a lot about what people might or might not do.
Doesn't it make sense, at the level of language/library enhancement,
to think about things with a more general functionality, like inject?
Not that sum would be out of place -- but given that both could exist,
what's the argument against inject?


David

--
David Alan Black
home: dbl...@candle.superlink.net
work: blac...@shu.edu
Web: http://pirate.shu.edu/~blackdav

Brian F. Feldman

unread,
Jan 7, 2001, 4:35:24 PM1/7/01
to
David Alan Black <dbl...@candle.superlink.net> wrote:
> Hello --
>
> On Mon, 8 Jan 2001, Brian F. Feldman wrote:
>
> > Except that I don't really ever see the need for the inject functionality
> > itself. A general sum method wouldn't prevent an inject method from being
> > created, and I feel it's much more generally important (if it were in
> > Enumerable, it feels natural next to min and max).
> >
> > I know you can define sum in terms of inject, but what is the point of
> > having inject if people are just going to use it to create sum?
>
> You're assuming a lot about what people might or might not do.
> Doesn't it make sense, at the level of language/library enhancement,
> to think about things with a more general functionality, like inject?
> Not that sum would be out of place -- but given that both could exist,
> what's the argument against inject?

I simply mean that even with a lack of an inject method due to there not
being a consensus on the name (personally, I think the name makes no sense,
as a native English speaker), it is worth it to have a sum method. I don't
mean that inject is useless, but that it shouldn't prevent sum from existing.

GOTO Kentaro

unread,
Jan 7, 2001, 4:19:42 PM1/7/01
to
In message "[ruby-talk:8782] Re: No :<, :>, etc. methods for Array"

on 01/01/08, "Brian F. Feldman" <gr...@FreeBSD.org> writes:
>I know you can define sum in terms of inject, but what is the point of
>having inject if people are just going to use it to create sum?

Well, I think we sometimes need to write something:

def product
@array.inject(1){|p,i| p *= i}
end

def sum
inject(element_type.induced_from(0)){|n,i| n.add!(i)}
end

def average_score
@profile.inject(0){|s,i| s += i.score}/@size
end

or

def pipeline
@process.inject(Product.new){|r,p| p.call(r)}
end

So, inject seems to be not only theoretical. Furthermore, I don't
need Array#sum so often. On the other hand, when I need sum I need
often also average, variance or square_error{|x| model(x)}. For
Enumerable, maybe a module `Statistics' is more useful.

Btw, I think that sum's argument for the empty case is convenient,
e.g.:

def sum(if_empty = 0) # Is the integer zero suitable?
total = if_empty
self.each {|x| total += x}
total
end

-- Gotoken

GOTO Kentaro

unread,
Jan 7, 2001, 5:12:37 PM1/7/01
to
In message "[ruby-talk:8785] Re: No :<, :>, etc. methods for Array"

on 01/01/08, "Brian F. Feldman" <gr...@FreeBSD.org> writes:
>I simply mean that even with a lack of an inject method due to there not
>being a consensus on the name (personally, I think the name makes no sense,
>as a native English speaker), it is worth it to have a sum method. I don't

Does anyone know the name of operator family which consists of $\sum$,
$\bigcup$ etc...? Jean?

-- Gotoken

David Alan Black

unread,
Jan 7, 2001, 5:20:30 PM1/7/01
to


I don't know it, but I doubt it's "Jean".

(ha ha)

GOTO Kentaro

unread,
Jan 7, 2001, 5:41:49 PM1/7/01
to
In message "[ruby-talk:8790] Re: No :<, :>, etc. methods for Array"

on 01/01/08, David Alan Black <dbl...@candle.superlink.net> writes:
>> Does anyone know the name of operator family which consists of $\sum$,
>> $\bigcup$ etc...? Jean?
>
>
>I don't know it, but I doubt it's "Jean".
>
>(ha ha)

Ouch, I shoud not omit verb until I understand English more... :-(

-- Gotoken

Avi Bryant

unread,
Jan 7, 2001, 5:46:09 PM1/7/01
to

On Mon, 8 Jan 2001, GOTO Kentaro wrote:

Actually, you were using a perfectly normal and correct, if casual,
English idiom... David was just playing on the ambiguity inherent in it.

David Alan Black

unread,
Jan 7, 2001, 5:53:08 PM1/7/01
to

On Mon, 8 Jan 2001, GOTO Kentaro wrote:

Why not? We do it all the time :-) It's very common -- like:

Anyone have a pen I could borrow? David?

Yours was only funny because the question was about a name (*not*
because you're not a native speaker -- in fact, that didn't even cross
my mind, which you should take as a compliment on your English :-)

Christoph Rippel

unread,
Jan 7, 2001, 6:11:00 PM1/7/01
to
> -----Original Message-----
> From: Brian F. Feldman [mailto:gr...@FreeBSD.org]
> Sent: Sunday, January 07, 2001 11:46 AM
> To: ruby-talk ML
> Subject: [ruby-talk:8782] Re: No :<, :>, etc. methods for Array
> Except that I don't really ever see the need for the inject functionality
> itself. A general sum method wouldn't prevent an inject method from being
> created, and I feel it's much more generally important (if it were in
> Enumerable, it feels natural next to min and max).
>
> I know you can define sum in terms of inject, but what is the point of
> having inject if people are just going to use it to create sum?
Obviously,

your question is ``only'' a matter of taste. Personally I already
dislike the inclusion of max,min and sort in the Array class instead
of creating a proper ``array > sortable array > numeric array'' class
hierarchy.


My secret wish for 1.7 would be the creation of a parallel (for
legacy reasons) more fine grained collection class hierarchy instead
of the current everything is either an ``Array or Hash'' strategy,
in which Arrays can take on the roles of Sets, MultiSets, Numerical
Arrays, Stacks, etc. . Introducing specialized collection classes
could make Ruby more efficient, clearly expresses the indent of usage
and could provide a definite answer on whether a general #sum method
should be included or what the proper definition of the intersection
of arrays should be ... .

> -----Original Message-----
> From: got...@hanare00.math.sci.hokudai.ac.jp
> [mailto:got...@hanare00.math.sci.hokudai.ac.jp]On Behalf Of GOTO
> Kentaro
> def sum(if_empty = 0) # Is the integer zero suitable?

An alternative would be the introduction of a ZERO and ONE constants
in the Numeric class (possibly overridden in subclasses)?

Christoph

GOTO Kentaro

unread,
Jan 7, 2001, 6:19:50 PM1/7/01
to
In message "[ruby-talk:8795] Re: No :<, :>, etc. methods for Array"

on 01/01/08, David Alan Black <dbl...@candle.superlink.net> writes:
>Yours was only funny because the question was about a name (*not*
>because you're not a native speaker -- in fact, that didn't even cross
>my mind, which you should take as a compliment on your English :-)

Oops, I might make serious mistake; I was so boorish that I fourced
you to explain your own pretty nice joke. I should mind the double
meaning of my question.

Thank you David and Avi :-)

-- Gotoken

GOTO Kentaro

unread,
Jan 7, 2001, 6:54:52 PM1/7/01
to
In message "[ruby-talk:8797] Re: No :<, :>, etc. methods for Array"

on 01/01/08, "Christoph Rippel" <cri...@primenet.com> writes:
>My secret wish for 1.7 would be the creation of a parallel (for
>legacy reasons) more fine grained collection class hierarchy instead
>of the current everything is either an ``Array or Hash'' strategy,
>in which Arrays can take on the roles of Sets, MultiSets, Numerical
>Arrays, Stacks, etc. . Introducing specialized collection classes
>could make Ruby more efficient, clearly expresses the indent of usage
>and could provide a definite answer on whether a general #sum method
>should be included or what the proper definition of the intersection
>of arrays should be ... .

I think such collections can be implemented as extension libraries if
one needs efficiency. Maybe designing interfaces is too difucult for
built-in specialized collections because we are greedy, and must want
many special methods for each of them, but our taste are more
different in case of special cases than in the general case. I have
such experience in the development working of NumArray (in RAA).

>> def sum(if_empty = 0) # Is the integer zero suitable?
>An alternative would be the introduction of a ZERO and ONE constants
>in the Numeric class (possibly overridden in subclasses)?

Because sum is defined in the context of container class, such
constants have to be given with their scope.

However, ONE and especially ZERO sound interesting. They will reduce
magics in code, perhaps.

-- Gotoken

Kevin Smith

unread,
Jan 7, 2001, 9:34:45 PM1/7/01
to
Christoph Rippel wrote:

>your question is ``only'' a matter of taste. Personally I already
>dislike the inclusion of max,min and sort in the Array class instead
>of creating a proper ``array > sortable array > numeric array'' class
>hierarchy.
>

>My secret wish for 1.7 would be the creation of a parallel (for
>legacy reasons) more fine grained collection class hierarchy instead
>of the current everything is either an ``Array or Hash'' strategy,
>in which Arrays can take on the roles of Sets, MultiSets, Numerical
>Arrays, Stacks, etc. . Introducing specialized collection classes
>could make Ruby more efficient, clearly expresses the indent of usage
>and could provide a definite answer on whether a general #sum method
>should be included or what the proper definition of the intersection
>of arrays should be ... .

I think I agree, and not for performance reasons.
Each class should do just one thing, and do it
well. That way, you only have to sift through and
learn the parts that you care about, rather than
an entire class with 100 methods.

Kevin

Dave Thomas

unread,
Jan 7, 2001, 9:50:33 PM1/7/01
to
"Brian F. Feldman" <gr...@FreeBSD.org> writes:

> So it's done to "discourage" people from doing it? E.g. currently the best
> way to compare version numbers would be:
>
> irb(main):003:0> ([1, 6, 2] <=> [1, 4, 3]) == 1

When we get around to adding versioning, I hope we'll have a version
class with comparison semantics.

Dave

Conrad Schneiker

unread,
Jan 7, 2001, 11:44:28 PM1/7/01
to
GOTO Kentaro wrote:

> In message "[ruby-talk:8780] Re: No :<, :>, etc. methods for Array"
> on 01/01/08, "Brian F. Feldman" <gr...@FreeBSD.org> writes:
> >class Array
> > def sum
> > total = self[0] # defaults to nil

> > self[1..-1].each {|x| total += x}
> > total
> > end


> >end
> >
> >It simplifies lots of things (especially mathematics) in Ruby to have
it,
> >and I believe it's generally useful enough that it should probably be
> >standard. What do you think?
>
> See:
> http://www.rubycentral.com/faq/rubyfaq-11.html#ss11.4
>
> `Enumerable#inject' is introduced there. That may be adopted if an
> apter method name is proposed.

You mean this isn't in the 1.7 queue? I thought we had previously agreed
that 'reduce' was the most appropriate term, largely because this was
compatible with the predominant math and comp. sci jargon, as
monumentalized by various ancient-to-modern programming languages (such as
Lisp, APL, Slim, ML, and Python).

Also, wasn't there some tangentally related discussion about adding
something like Python's (and ML's?) zip method?

Conrad Schneiker
(This note is unofficial and subject to improvement without notice.)

Yasushi Shoji

unread,
Jan 8, 2001, 12:07:45 AM1/8/01
to
At Mon, 8 Jan 2001 11:50:33 +0900,
Dave Thomas wrote:

> > So it's done to "discourage" people from doing it? E.g. currently
> > the best way to compare version numbers would be:
> >
> > irb(main):003:0> ([1, 6, 2] <=> [1, 4, 3]) == 1
>
> When we get around to adding versioning, I hope we'll have a version
> class with comparison semantics.

I realized the other day, when I tried to create class Version, that
creating class Version which is generic enough to satisfy all the
version scheme we have is very close to impossible.

So I ended up with a class for Ruby versioning scheme with only what I
need. constructor for a String, an Array, and Integers, #major,
#minor, #teeny, and #<=> for Comparable.

any one has better idea?
--
yashi

Dave Thomas

unread,
Jan 8, 2001, 12:36:46 AM1/8/01
to
Yasushi Shoji <ya...@yashi.com> writes:

> I realized the other day, when I tried to create class Version, that
> creating class Version which is generic enough to satisfy all the
> version scheme we have is very close to impossible.
>
> So I ended up with a class for Ruby versioning scheme with only what I
> need. constructor for a String, an Array, and Integers, #major,
> #minor, #teeny, and #<=> for Comparable.

> any one has better idea?

Not better, but perhaps additional.

Should a library's version information also be used to record
dependencies?

module Wombat

Version "1.2.3" {
requires "marsupial" # no qualifier means any version
requires "eucalyptus" :> "1.0" # at least this version
requires "sleep" :> "0.9" :< "1.5" # in range
requires "skippy" "5.4" # exact (same as :== "5.4")
}

end


We can query a module's version information from the outside

Wombat.version #=> Version(1.2.3)

Wombat.requirements.each {|req| ...

and so on. I _think_ this can all be implemented at the Ruby level.


Looks scary, but it puts all the dependency stuff in one place, which
will greatly help in the grand unified library project (gulp).

Dave

Christoph Rippel

unread,
Jan 8, 2001, 12:54:31 AM1/8/01
to
> -----Original Message-----
> From: got...@hanare00.math.sci.hokudai.ac.jp
> [mailto:got...@hanare00.math.sci.hokudai.ac.jp]On Behalf Of GOTO
> Kentaro
> Sent: Sunday, January 07, 2001 03:55 PM
> To: ruby-talk ML
> Subject: [ruby-talk:8800] Re: No :<, :>, etc. methods for Array

> I think such collections can be implemented as extension libraries if
> one needs efficiency. Maybe designing interfaces is too difucult for
> built-in specialized collections because we are greedy, and must want
> many special methods for each of them, but our taste are more
> different in case of special cases than in the general case. I have
> such experience in the development working of NumArray (in RAA).

I see your point ... . I guess my idea was to be less greedy
and to reorganize the current Array and Hash classes in a class
hierarchy which effectively takes away (and sometimes adding and/or
redefining) most of their current functionality. The core languages
does not provide among others things a predefined Stack class,
(Multi)Set (or their ordered variants)- instead this functionality
was ``crammed into'' the Hash and Array container classes taking
away clarity of intent, functionality, possible optimizations and
as Kevin points out creating class interfaces with a pretty steep
learning curve.

In my opinion it would be a good thing if the standard Ruby
distribution would ship with a ``nice library'' of well integrated
basic container classes


> >> def sum(if_empty = 0) # Is the integer zero suitable?
> >An alternative would be the introduction of a ZERO and ONE constants
> >in the Numeric class (possibly overridden in subclasses)?
>
> Because sum is defined in the context of container class, such
> constants have to be given with their scope.

From would you are saying it seems that the container class should
effectively provide this generic zero. What about something like

class ContainerClass
ZERO = 0 # or something similar like the hypothetical Numeric::ZERO
def def sum(if_empty = type::ZERO)
..
end
...
end

This way you can override the generic ZERO in a specialized
ContainerClass

> However, ONE and especially ZERO sound interesting. They will reduce
> magics in code, perhaps.

Thanks

Christoph

Ben Tilly

unread,
Jan 8, 2001, 1:04:23 AM1/8/01
to
"Christoph Rippel" <cri...@primenet.com> wrote:

>
> > -----Original Message-----
> > From: got...@hanare00.math.sci.hokudai.ac.jp
[...]
>I see your point ... . I guess my idea was to be less greedy
>and to reorganize the current Array and Hash classes in a class
>hierarchy which effectively takes away (and sometimes adding and/or
>redefining) most of their current functionality. The core languages
>does not provide among others things a predefined Stack class,
>(Multi)Set (or their ordered variants)- instead this functionality
>was ``crammed into'' the Hash and Array container classes taking
>away clarity of intent, functionality, possible optimizations and
>as Kevin points out creating class interfaces with a pretty steep
>learning curve.
>
>In my opinion it would be a good thing if the standard Ruby
>distribution would ship with a ``nice library'' of well integrated
>basic container classes
[...]

I have mentioned before, perhaps I should mention again.

The right container modules would (when combined with
mix-ins) provide a complete equivalent to Perl's tie.
As things stand someone who wanted to write a version
of Hash or Array which was tied to disk through a dbm
library like Berkeley DB would need to reimplement a
lot of methods.

As an optimization Array and Hash might reimplement
some of these things directly, but still the overall
structure would be good to have around.

Cheers,
Ben
_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com

Ben Tilly

unread,
Jan 8, 2001, 12:57:57 AM1/8/01
to
Dave Thomas <Da...@PragmaticProgrammer.com> wrote:
>
>Yasushi Shoji <ya...@yashi.com> writes:
>
> > I realized the other day, when I tried to create class Version, that
> > creating class Version which is generic enough to satisfy all the
> > version scheme we have is very close to impossible.
> >
> > So I ended up with a class for Ruby versioning scheme with only what I
> > need. constructor for a String, an Array, and Integers, #major,
> > #minor, #teeny, and #<=> for Comparable.
>
> > any one has better idea?
>
>Not better, but perhaps additional.

To a big extent with versioning it is better to be consistent
than allow arbitrariness. The x.y.z notation is standard
enough and works well enough to settle on.

In that spirit should the idea that "odd minor versions are
development" be given official substance?

>Should a library's version information also be used to record
>dependencies?

Yes.

> module Wombat
>
> Version "1.2.3" {
> requires "marsupial" # no qualifier means any
>version
> requires "eucalyptus" :> "1.0" # at least this version
> requires "sleep" :> "0.9" :< "1.5" # in range
> requires "skippy" "5.4" # exact (same as :== "5.4")
> }
>
> end
>

Note that the "at least" will be the most common.

"In range" will be inefficient to implement. Is it really
needed in general? What happens if Foo needs Bar, and both
support intersecting ranges?

However if someone specifies a version, it may make sense
to by default not let them cross major versions. So perhaps
a range of major versions make sense?


>
>We can query a module's version information from the outside
>
> Wombat.version #=> Version(1.2.3)
>
> Wombat.requirements.each {|req| ...
>
>and so on. I _think_ this can all be implemented at the Ruby level.
>

IMHO it would be extremely good to have a standard naming
scheme so that multiple versions can co-exist in the same
file-system. I think it is acceptable for such a naming
scheme to assume that you are not limited by the old 8.3
rule.


>
>Looks scary, but it puts all the dependency stuff in one place, which
>will greatly help in the grand unified library project (gulp).
>

Yup. Debian has it. Perl does not. Having used both I
think it is important to have ways to track versioning
requirements beyond just, "Upgrade everything and hope
that the current versions play well together."

Christoph Rippel

unread,
Jan 8, 2001, 1:28:18 AM1/8/01
to
> -----Original Message-----
> From: Ben Tilly [mailto:ben_...@hotmail.com]
> Sent: Sunday, January 07, 2001 10:04 PM
> To: ruby-talk ML
> Subject: [ruby-talk:8822] Re: No :<, :>, etc. methods for Array
> I have mentioned before, perhaps I should mention again.
>
> The right container modules would (when combined with
> mix-ins) provide a complete equivalent to Perl's tie.
Since I am pretty about ignorant about Perl (among many
other things) what is a good pointer to ``Perl's tie''?
(I confess I was thinking more along the lines of the
C++-STL or the Java Container classes.)

Christoph

Christoph Rippel

unread,
Jan 8, 2001, 1:58:51 AM1/8/01
to
> If you have Perl installed the following commands will
> tell you more about tie:
>
> perldoc -f tie
> perldoc perltie
> perldoc AnyDBM_File
....
> Cheers,
> Ben

Thanks

Christoph

Ben Tilly

unread,
Jan 8, 2001, 1:51:32 AM1/8/01
to
If you have Perl installed the following commands will
tell you more about tie:

perldoc -f tie
perldoc perltie
perldoc AnyDBM_File

And if you also have Berkeley DB installed then:

perldoc DB_File

It is a very handy interface to use in a lot of scripting
problems. And it looks very impressive. But in fact all
that the Perl folks did is allow a class that provides a
few basic methods to have native datatypes "tied" to it,
and Perl simulates all of the native stuff by making the
appropriate method calls.

Since Perl's type system is implemented in its syntax,
this cannot be duplicated without direct language support.
But most of Ruby's type system is implemented in its OO
structure and the syntax of how you access an array, hash,
and even call anonymous functions is the same. So Ruby
would get equivalent flexibility by having a series of
well thought-out modules (similar to Enumerable) which
would allow someone to get a drop-in replacement for the
native data-types without having to write most of the
interface themselves.

For the record the biggest use of tie in Perl is accessing
dbm files. The full interface (much of which is optional)
involves writing the following methods:

TIEHASH
FETCH
STORE
EXISTS
DELETE
CLEAR
FIRSTKEY
NEXTKEY
DESTROY

If you write those (or as many as you will be needing) then
you can make virtually anything look like a hash.

Christoph Rippel

unread,
Jan 8, 2001, 3:31:39 AM1/8/01
to

"Christoph Rippel" <cri...@primenet.com> wrote in message
news:MGEAJFIIJOCJJJKGKG...@primenet.com...

> From would you are saying it seems that the container class should
> effectively provide this generic zero. What about something like
>
> class ContainerClass
> ZERO = 0 # or something similar like the hypothetical Numeric::ZERO
> def def sum(if_empty = type::ZERO)
> ..
> end
> ...
> end
I guess the ``type::'' prefix is totally unnecessary ... . This makes only
sense
in the context of a ``SumModule'' to be mixed into a ContainerClass
providing
this missing ZERO (alternatively the ContainerClass could provide a #zero
method.)

Christoph

David Alan Black

unread,
Jan 8, 2001, 7:10:19 AM1/8/01
to
On Mon, 8 Jan 2001, Ben Tilly wrote:

> I have mentioned before, perhaps I should mention again.
>
> The right container modules would (when combined with
> mix-ins) provide a complete equivalent to Perl's tie.
> As things stand someone who wanted to write a version
> of Hash or Array which was tied to disk through a dbm
> library like Berkeley DB would need to reimplement a
> lot of methods.

True, but when you write STORE() and FETCH() and all that in Perl,
you're also reimplementing a lot of methods. One could argue the
other way -- namely, that in Ruby, the basic mechanism for redefining
methods is so powerful that *all* you have to do to get tie
functionality is reimplement some methods. They happen to be called
things like #[]=, rather than STORE(), but they're already there.

To put it another way: even a "naive" Ruby approach to creating a
tied hash:

class SomeTiedHash < Hash

alias ....

def initialize(*n)
# do some stuff, open a file, whatever
super(*n)
end

def []=(k,v)
oldset(k,v)
@fh.puts "#{k}: #{v}".....
end

end

does actually create a tied hash. I'm not saying there are no
possible reasons to do some modularization and so forth -- but I don't
see any big obstacles or logjams to doing tied things already.

Hugh Sasse Staff Elec Eng

unread,
Jan 8, 2001, 7:07:45 AM1/8/01
to
On Mon, 8 Jan 2001, Dave Thomas wrote:

> Should a library's version information also be used to record
> dependencies?
>
> module Wombat
>
> Version "1.2.3" {
> requires "marsupial" # no qualifier means any version
> requires "eucalyptus" :> "1.0" # at least this version
> requires "sleep" :> "0.9" :< "1.5" # in range
> requires "skippy" "5.4" # exact (same as :== "5.4")

I think it would be useful to have "and possibly earlier", as well.
This would mean: "It might work -- try it and let me know!". This is
different from asserting that it will work with all versions, or saying
it will only work with later versions.

I mentioned before the need for Except, so a broken release of some
library can be rejected, when earlier and later ones work OK.

Why do we need the colons? Can't the relational operators be
overloaded for this?

One more wish: If you miss out a dependency, Ruby should tell you.
If you declare a spurious dependency -- a module you do not actually
load or require, then Ruby should tell you.

> }
>
> end


>
> Looks scary, but it puts all the dependency stuff in one place, which
> will greatly help in the grand unified library project (gulp).

Ruby enters L-space... :-)
>
> Dave
>
Hugh
h...@dmu.ac.uk

jwei...@one.net

unread,
Jan 8, 2001, 7:07:20 AM1/8/01
to
>>>>> "Brian" == Brian F Feldman <gr...@FreeBSD.org> writes:

Brian> I know you can define sum in terms of inject, but what is
Brian> the point of having inject if people are just going to use
Brian> it to create sum?

I've used inject (or "reduce") in the following to build a list from
scratch ...

mods.reduce([]) { |mod,list| local_methods(mod) | list }.sort

I use it as often for general things as I do for summing.

--
-- Jim Weirich jwei...@one.net http://w3.one.net/~jweirich
---------------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

hipster

unread,
Jan 8, 2001, 7:36:05 AM1/8/01
to
On Mon, 08 Jan 2001 14:36:46 +0900, Dave Thomas wrote:
[snip]

> Not better, but perhaps additional.
>
> Should a library's version information also be used to record
> dependencies?
>
> module Wombat
>
> Version "1.2.3" {
> requires "marsupial" # no qualifier means any version
> requires "eucalyptus" :> "1.0" # at least this version
^^
:>=

> requires "sleep" :> "0.9" :< "1.5" # in range
> requires "skippy" "5.4" # exact (same as :== "5.4")

It might be more intuitive to use the operator-less notation to denote
"at least", see [ruby-talk:5613]. This seems to me to be the most
common usage; a script requires x.y, and doesn't care if fix x.y.1 is
present. Ruby could warn before loading libs with major number
increments, as the interface will probably have changed. A common
versioning system would help a lot here.

[snip]


> Looks scary, but it puts all the dependency stuff in one place, which
> will greatly help in the grand unified library project (gulp).

Agreed.

Michel

Ben Tilly

unread,
Jan 8, 2001, 7:47:29 AM1/8/01
to
David Alan Black <dbl...@candle.superlink.net> wrote:
>
>On Mon, 8 Jan 2001, Ben Tilly wrote:
>
> > I have mentioned before, perhaps I should mention again.
> >
> > The right container modules would (when combined with
> > mix-ins) provide a complete equivalent to Perl's tie.
> > As things stand someone who wanted to write a version
> > of Hash or Array which was tied to disk through a dbm
> > library like Berkeley DB would need to reimplement a
> > lot of methods.
>
>True, but when you write STORE() and FETCH() and all that in Perl,
>you're also reimplementing a lot of methods. One could argue the
>other way -- namely, that in Ruby, the basic mechanism for redefining
>methods is so powerful that *all* you have to do to get tie
>functionality is reimplement some methods. They happen to be called
>things like #[]=, rather than STORE(), but they're already there.

I would not advocate using the names used in Perl.

>To put it another way: even a "naive" Ruby approach to creating a
>tied hash:
>
> class SomeTiedHash < Hash
>
> alias ....
>
> def initialize(*n)
> # do some stuff, open a file, whatever
> super(*n)
> end
>
> def []=(k,v)
> oldset(k,v)
> @fh.puts "#{k}: #{v}".....
> end
>
> end
>
>does actually create a tied hash. I'm not saying there are no
>possible reasons to do some modularization and so forth -- but I don't
>see any big obstacles or logjams to doing tied things already.
>

In your book I count 40 methods for hashes. Matching the
full behaviour of arrays would be worse.

Tying out to the full behaviour takes a lot more work than
it needs to. A few well-chosen modules could make this
much easier.

Hal E. Fulton

unread,
Jan 8, 2001, 8:01:42 AM1/8/01
to

Ah, Gotoken, he is only kidding you. There is nothing really ambiguous
about what you said... :)

Hal


David Alan Black

unread,
Jan 8, 2001, 8:09:25 AM1/8/01
to
On Mon, 8 Jan 2001, Ben Tilly wrote:

> In your book I count 40 methods for hashes. Matching the
> full behaviour of arrays would be worse.

Ummmm, not my book. (Which is called "Law in Film" -- hey, I never
thought I'd have an excuse to plug it here :-) Other Dav*. Or,
more precisely, one of the other Dav*s. (I guess I should find some
comfort in the fact that even being named Clemens doesn't help you
around here :-)

> Tying out to the full behaviour takes a lot more work than
> it needs to. A few well-chosen modules could make this
> much easier.

But not every method would need to be redefined for every tying
situation. Again, I'm not objecting to the idea of some kind of
modularization of this, though I am having some trouble thinking of
a case where I would find it insufficient to redefine a few things
like #[], #[]=, possibly has_key?, etc.

I'm willing to be persuaded, just currently see this as a solution in
search of a problem.

ts

unread,
Jan 8, 2001, 7:54:29 AM1/8/01
to
>>>>> "B" == Ben Tilly <ben_...@hotmail.com> writes:

B> As things stand someone who wanted to write a version
B> of Hash or Array which was tied to disk through a dbm
B> library like Berkeley DB would need to reimplement a
B> lot of methods.

pigeon% wc -l bdb.c
4264 bdb.c
pigeon%

pigeon% wc -l BerkeleyDB.xs BerkeleyDB.pm
3655 BerkeleyDB.xs
1189 BerkeleyDB.pm
4844 total
pigeon%

Sorry but I still prefer the ruby version


Guy Decoux

ts

unread,
Jan 8, 2001, 9:45:47 AM1/8/01
to
>>>>> "B" == Ben Tilly <ben_...@hotmail.com> writes:

B> 1. Are you aware that the module is largely documentation?

True perhaps for DB_File but not for BerkeleyDB, verify it (no
documentation in .xs and .pm)

pigeon% ls -al BerkeleyDB.*
-r--r--r-- 1 ts ts 24530 Jun 5 2000 BerkeleyDB.pm
-r--r--r-- 1 ts ts 45409 Jun 5 2000 BerkeleyDB.pod
-r--r--r-- 1 ts ts 39276 Jun 5 2000 BerkeleyDB.pod.P
-r--r--r-- 1 ts ts 91118 Jun 5 2000 BerkeleyDB.xs
pigeon%


B> 2. Are you aware that the Perl interface to that specific
B> module is largely stuff that does not fit into the
B> idea of a hash?

In that case don't take this example. This was you who has given the
example of BerkeleyDB not me.

B> 3. Are you aware that Perl's C API is a definite sore spot?

I know this and I know *why* I prefer write extension in ruby rather than
perl.


Guy Decoux

Ben Tilly

unread,
Jan 8, 2001, 9:37:43 AM1/8/01
to
ts <dec...@moulon.inra.fr> wrote:
>
> >>>>> "B" == Ben Tilly <ben_...@hotmail.com> writes:
>
>B> As things stand someone who wanted to write a version
>B> of Hash or Array which was tied to disk through a dbm
>B> library like Berkeley DB would need to reimplement a
>B> lot of methods.
>
>pigeon% wc -l bdb.c
> 4264 bdb.c
>pigeon%
>
>pigeon% wc -l BerkeleyDB.xs BerkeleyDB.pm
> 3655 BerkeleyDB.xs
> 1189 BerkeleyDB.pm
> 4844 total
>pigeon%
>
> Sorry but I still prefer the ruby version

Ask yourself the following questions first.

1. Are you aware that the module is largely documentation?

2. Are you aware that the Perl interface to that specific

module is largely stuff that does not fit into the

idea of a hash?


3. Are you aware that Perl's C API is a definite sore spot?

4. Since the essential support for the concept is part of
Ruby from the ground up rather than hacked on top as a
special case like it is in Perl, I would expect a Ruby
implementation to be both simpler to do and work more
smoothly than Perl's version. (*)

Cheers,
Ben

PS Perl's version of tie is actually built all of the way
through the source-code. Just last weekend I learned of
yet another bug in Perl due to this. local() and tie()
(at least when you are tying filehandles) do not play
well together.

Ben Tilly

unread,
Jan 8, 2001, 9:49:54 AM1/8/01
to
David Alan Black <dbl...@candle.superlink.net> wrote:
>
>On Mon, 8 Jan 2001, Ben Tilly wrote:
>
> > In your book I count 40 methods for hashes. Matching the
> > full behaviour of arrays would be worse.
>
>Ummmm, not my book. (Which is called "Law in Film" -- hey, I never
>thought I'd have an excuse to plug it here :-) Other Dav*. Or,
>more precisely, one of the other Dav*s. (I guess I should find some
>comfort in the fact that even being named Clemens doesn't help you
>around here :-)

Erk. Oops.

> > Tying out to the full behaviour takes a lot more work than
> > it needs to. A few well-chosen modules could make this
> > much easier.
>
>But not every method would need to be redefined for every tying
>situation. Again, I'm not objecting to the idea of some kind of
>modularization of this, though I am having some trouble thinking of
>a case where I would find it insufficient to redefine a few things
>like #[], #[]=, possibly has_key?, etc.

The idea of tie is to have a totally new implementation
that happens to have a similar interface to something
native. Given that you want to have a new implementation,
you cannot inherit from the existing one. Therefore you
either implement some minimal subset of the existing one,
or else you do rewrite a lot of (admittedly not complex)
methods. Many of which exist to be syntactic sugar.

For new code you can just use the subset. Where tie
becomes very handy is when you want to take a large body
of existing code, not have to look at it, but still
temporarily replace the implementation.

>I'm willing to be persuaded, just currently see this as a solution in
>search of a problem.
>

It is the same problem that Enumerable addresses. Turn
building a complex and widely used interface into building
a rather small interface. Many of the methods that are in
Array and Hash today are there as either syntactic sugar or
for convenience. Why not make it easy for others to reuse
the convenience of that interface?

Cheers,
Ben

GOTO Kentaro

unread,
Jan 8, 2001, 10:52:10 AM1/8/01
to
In message "[ruby-talk:8820] Re: No :<, :>, etc. methods for Array"

on 01/01/08, "Christoph Rippel" <cri...@primenet.com> writes:
>I see your point ... . I guess my idea was to be less greedy
>and to reorganize the current Array and Hash classes in a class
>hierarchy which effectively takes away (and sometimes adding and/or
>redefining) most of their current functionality. The core languages
>does not provide among others things a predefined Stack class,
>(Multi)Set (or their ordered variants)- instead this functionality
>was ``crammed into'' the Hash and Array container classes taking
>away clarity of intent, functionality, possible optimizations and
>as Kevin points out creating class interfaces with a pretty steep
>learning curve.
>
>In my opinion it would be a good thing if the standard Ruby
>distribution would ship with a ``nice library'' of well integrated
>basic container classes

I see what you say just now. Thank you Christoph. Well, such
development can be done efficiently by release-test-improve loop. So,
I'd like to wait RAA-entry(s) of containers written by anyone. If
cachy one appears for everyone, Matz adopt that as a standard library.

>class ContainerClass
>ZERO = 0 # or something similar like the hypothetical Numeric::ZERO
>def def sum(if_empty = type::ZERO)
>..
>end
>...
>end
>
>This way you can override the generic ZERO in a specialized
>ContainerClass

I think operations like sum is a kind of cross-hierarchical spec of
container and it should be provided as mix-in, perhaps.

Cle and me had a series of discussions about container hierarchy in
the context of how to realize sutably reverse ordered version of each.
You can find them in some threads, e.g.:

`New feature for Ruby'
http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb/ruby/ruby-talk/407?404-621

Thanks,

-- Gotoken

Christoph Rippel

unread,
Jan 8, 2001, 12:24:26 PM1/8/01
to
> -----Original Message-----
> From: got...@hanare00.math.sci.hokudai.ac.jp
> [mailto:got...@hanare00.math.sci.hokudai.ac.jp]On Behalf Of GOTO
> Kentaro
> Sent: Monday, January 08, 2001 07:52 AM
> To: ruby-talk ML
> Subject: [ruby-talk:8878] good container?
> I see what you say just now. Thank you Christoph. Well, such
> development can be done efficiently by release-test-improve loop. So,
> I'd like to wait RAA-entry(s) of containers written by anyone. If
> cachy one appears for everyone, Matz adopt that as a standard library.
This seems like a pragmatic and probably best course of action.

> >class ContainerClass
> >ZERO = 0 # or something similar like the hypothetical Numeric::ZERO
> >def def sum(if_empty = type::ZERO)
> >..
> >end
> >...
> >end
> >
> >This way you can override the generic ZERO in a specialized
> >ContainerClass
>
> I think operations like sum is a kind of cross-hierarchical spec of
> container and it should be provided as mix-in, perhaps.
Agreed ..

> Cle and me had a series of discussions about container hierarchy in
> the context of how to realize sutably reverse ordered version of each.
> You can find them in some threads, e.g.:
>
> `New feature for Ruby'
> http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb/ruby/ruby-talk/407?404-621
Interesting thread - funny this is (almost) exactly what people are
discussing in the current ``Backward Range implementation'' thread.

Thanks!
Christoph

David Alan Black

unread,
Jan 8, 2001, 1:36:51 PM1/8/01
to
On Mon, 8 Jan 2001, Ben Tilly wrote:

> The idea of tie is to have a totally new implementation
> that happens to have a similar interface to something
> native. Given that you want to have a new implementation,
> you cannot inherit from the existing one. Therefore you
> either implement some minimal subset of the existing one,
> or else you do rewrite a lot of (admittedly not complex)
> methods. Many of which exist to be syntactic sugar.
>
> For new code you can just use the subset. Where tie
> becomes very handy is when you want to take a large body
> of existing code, not have to look at it, but still
> temporarily replace the implementation.
>

[me:]


> >I'm willing to be persuaded, just currently see this as a solution in
> >search of a problem.
> >
> It is the same problem that Enumerable addresses. Turn
> building a complex and widely used interface into building
> a rather small interface. Many of the methods that are in
> Array and Hash today are there as either syntactic sugar or
> for convenience. Why not make it easy for others to reuse
> the convenience of that interface?

In principle that's fine -- laudable, even :-) -- I'm just not getting
exactly what you mean in practice. A module called TieHash? Tieable?
What would it consist of? I keep coming back to the fact that, if I
wanted to write a program using hashish... ummm... hash-like syntax, I
would give my class a []= method, and so forth. I'm not clear on what
would be gained by inheriting from TieHash or something like that.

In Perl there's a kind of middle layer, because you can't just define
STORE() and have an object know what to do. You have to have
something like tie(), so that the line can be drawn, so to speak, from
the object through the syntax ($hash{x} = "whatever") to STORE(). I
suppose my question is: does all of that really even have to happen in
Ruby, given how malleable everything is? In Ruby you *can* "just
define" these things. The fact that []= is a method seems to me to
change the logic of tying completely.

Or is that a separate issue? Back to question 1: if you are
describing something along the lines of a Tieable module, what would
be in it?

Ben Tilly

unread,
Jan 8, 2001, 2:48:49 PM1/8/01
to
David Alan Black <dbl...@candle.superlink.net> wrote:
>On Mon, 8 Jan 2001, Ben Tilly wrote:
[...]

> > It is the same problem that Enumerable addresses. Turn
> > building a complex and widely used interface into building
> > a rather small interface. Many of the methods that are in
> > Array and Hash today are there as either syntactic sugar or
> > for convenience. Why not make it easy for others to reuse
> > the convenience of that interface?
>
>In principle that's fine -- laudable, even :-) -- I'm just not getting
>exactly what you mean in practice. A module called TieHash? Tieable?
>What would it consist of? I keep coming back to the fact that, if I
>wanted to write a program using hashish... ummm... hash-like syntax, I
>would give my class a []= method, and so forth. I'm not clear on what
>would be gained by inheriting from TieHash or something like that.

Say modules called ArrayInterface, HashInterface and
StringInterface.

If you want to use it you would have to write []= and so
on, but the so-on to get the whole interface would be much
smaller than it would be now.

For instance if Ruby settles on a native reduce() method,
well there is no need to write that method in every class
that wants to do something like an array, is there?

>In Perl there's a kind of middle layer, because you can't just define
>STORE() and have an object know what to do. You have to have
>something like tie(), so that the line can be drawn, so to speak, from
>the object through the syntax ($hash{x} = "whatever") to STORE(). I
>suppose my question is: does all of that really even have to happen in
>Ruby, given how malleable everything is? In Ruby you *can* "just
>define" these things. The fact that []= is a method seems to me to
>change the logic of tying completely.

Look at the list of methods for widely used basic classes.

How many of those are really basic, and how many can easily
be written in terms of the rest?

Now I agree that telling Perl people that this is tie is
just advertising. The design of Ruby makes it trivial.
The internal design of Perl does not.

>Or is that a separate issue? Back to question 1: if you are
>describing something along the lines of a Tieable module, what would
>be in it?
>

You would not have a single Tieable module.

You would have modules for each class you wanted to emulate
that let you define a basic list of methods and get the
entire interface. A class which wished to provide what
Perl folks would think of as a tied interface would just
implement the basic and obvious methods, then mixin the rest
of the interface.

Instead of calling a magic tie function that did deep and
magic things, you would call "new".

If you think that this sounds like a trivial idea, then you
probably understood it correctly. This isn't a hard thing
to do. It isn't a hard thing to support. It isn't a deep
change to the language.

But I suspect it would be convenient.

Aleksi Niemel

unread,
Jan 9, 2001, 7:15:46 AM1/9/01
to
Hello,

At least David Alan Black and Ben Tilly have been conversating, the latter's
last comment being:

> Say modules called ArrayInterface, HashInterface and
> StringInterface.
>
> If you want to use it you would have to write []= and so
> on, but the so-on to get the whole interface would be much
> smaller than it would be now.

Ok. I've been following this thread with great interest, but I've been
somewhat lost. That's mostly due to my quite limited knowledge of Perl Tying
concept. I always thought it's quite simple, but it's referred everywhere as
pure magic. Now I guess I got on the map again.

So if I understand correctly we would like to have (sorry being wordy, I
just wanted to be clear):

module StandardHashClassMethodInterface
def []; end
def new; end
end

module StandardHashInstanceMethodInterface
def []; end # alias fetch
def []=; end # alias store
def delete; end
def keys; end # or first_key, next_key iterators
# which is probably better
def has_key?; end # alias key? and
# include? (which is in Enumerable too)
# OTOH, this could be defined in terms of
# Hash#keys, but we'd lose O(1) look-up
def rehash; end
end

module StandardHashConvenienceInterface
=begin
Convenience methods can be described in terms of standard
instance method interface.

In most cases one would like to optimize some of these methods
by redefining them.

==
clear
default
default=
delete_if
each
each_key
each_pair
each_value
empty?
has_value?
include?
index
indexes
indices
invert
key?
length
member?
reject
reject!
replace
shift
size
sort
to_a
to_s
update
value?
values
=end
end

And then our current hash and all user defined hashes could be done by
saying:

class HashAlike
include StandardHashInstanceMethodInterface
# and by defining 6 or 7 methods the interface *requires*

include Enumerable
# and by redefining methods for speed if needed
# like include? for Hash

include StandardHashConvenienceInterface
# and by redefining methods for speed if needed
end

Ben, is this explicit separation and grouping of methods to interfaces
(which might be expressed by default in terms of other interfaces) what you
have in mind?

If so, then we might proceed to define interfaces for Strings and Arrays,
and what else needed.

If I understand the underlying concept correctly, by imposing some more
structure to current classes, and keeping eye on backwards compatibility, we
ease up documentation of current behaviour and implementation of user made
FooAlike -datastructures. If we get Perl's TIE behaviour as a bonus, this is
surely the way to go.

This discussion reminds me of the recent String as IO (or the otherway
round) thread. IIRC, the end result was that the APIs should be defined more
clearly and then masquerading classes to act like other classes would be
trivial. Aren't we approach that solution?

- Aleksi

David Alan Black

unread,
Jan 9, 2001, 8:20:41 AM1/9/01
to
Hello -

On Tue, 9 Jan 2001, [iso-8859-1] Aleksi Niemel=E4 wrote:

> Hello,
>=20
> At least David Alan Black and Ben Tilly have been conversating, the latte=
r's
> last comment being:=20
>=20


> > Say modules called ArrayInterface, HashInterface and
> > StringInterface.
> >

> > If you want to use it you would have to write []=3D and so


> > on, but the so-on to get the whole interface would be much
> > smaller than it would be now.

>=20


> Ok. I've been following this thread with great interest, but I've been

> somewhat lost. That's mostly due to my quite limited knowledge of Perl Ty=
ing
> concept. I always thought it's quite simple, but it's referred everywhere=


as
> pure magic. Now I guess I got on the map again.

I think the whole Perl tying part of this is not all that relevant. In
Ruby, right now, it's pretty easy to do everything that a Perl tied class
does. Standard interface classes could clean things up a little in that
area (mainly by not having unnecessary methods defined), but the basic
ability to do the equivalent of Perl tying is already there.


David

--=20

Ben Tilly

unread,
Jan 9, 2001, 9:18:04 AM1/9/01
to
Aleksi Niemel<aleksi....@cinnober.com> wrote:
>
>Hello,

>
>At least David Alan Black and Ben Tilly have been conversating, the
>latter's
>last comment being:
>
> > Say modules called ArrayInterface, HashInterface and
> > StringInterface.
> >
> > If you want to use it you would have to write []= and so

> > on, but the so-on to get the whole interface would be much
> > smaller than it would be now.
>
>Ok. I've been following this thread with great interest, but I've been
>somewhat lost. That's mostly due to my quite limited knowledge of Perl
>Tying

>concept. I always thought it's quite simple, but it's referred everywhere
>as
>pure magic. Now I guess I got on the map again.

It is a simple magic. :-)

Imagine a language where you are constantly telling the
language everywhere that you have a duck because it is
walking like a duck and talking like a duck. This is
built into everything that you do. Then suddenly you
find out that it isn't really a duck after all.

What happened?

Magic!

(They even call it that in the source-code.)

In Ruby there is no surprise. All that walking and talking
like a duck means is that you have the methods that a duck
does. In Perl there is great surprise because you have
just violated (in a useful way, but still) a basic pattern of
how the language works.

>So if I understand correctly we would like to have (sorry being wordy, I
>just wanted to be clear):

[...]


>And then our current hash and all user defined hashes could be done by
>saying:
>
> class HashAlike
> include StandardHashInstanceMethodInterface
> # and by defining 6 or 7 methods the interface *requires*
>
> include Enumerable
> # and by redefining methods for speed if needed
> # like include? for Hash
>
> include StandardHashConvenienceInterface
> # and by redefining methods for speed if needed
> end
>
>Ben, is this explicit separation and grouping of methods to interfaces
>(which might be expressed by default in terms of other interfaces) what you
>have in mind?

Yes.

>If so, then we might proceed to define interfaces for Strings and Arrays,
>and what else needed.
>
>If I understand the underlying concept correctly, by imposing some more
>structure to current classes, and keeping eye on backwards compatibility,
>we
>ease up documentation of current behaviour and implementation of user made
>FooAlike -datastructures. If we get Perl's TIE behaviour as a bonus, this
>is
>surely the way to go.

You understand exactly. Getting Perl's tie behaviour is
not really a bonus. It is good advertising which takes
advantage of the fact that few Perl programmers actually
understand anything about tie other than the fact that it
looks like magic and is a cool feature.

>This discussion reminds me of the recent String as IO (or the otherway
>round) thread. IIRC, the end result was that the APIs should be defined
>more
>clearly and then masquerading classes to act like other classes would be
>trivial. Aren't we approach that solution?

Exactly.

However Strings in particular may be a special case. We
might want to resolve whatever to a string for some things.
(Specifically when used as hash keys and when someone tries
to match against them.)

One note. A good deal of Ruby's current library is
designed after how Perl works. For scripting I think that
this is an excellent choice. So even though it should be
easy to imitate a built-in class, IMO the built-in classes
should continue to have rich interfaces.

David Alan Black

unread,
Jan 9, 2001, 9:46:47 AM1/9/01
to
Hello --

On Tue, 9 Jan 2001, Ben Tilly wrote:

> You understand exactly. Getting Perl's tie behaviour is
> not really a bonus. It is good advertising which takes
> advantage of the fact that few Perl programmers actually
> understand anything about tie other than the fact that it
> looks like magic and is a cool feature.

Hmmm.... Why is that good advertising? Well, we can agree
to disagree on that one :-)

> One note. A good deal of Ruby's current library is
> designed after how Perl works. For scripting I think that
> this is an excellent choice. So even though it should be
> easy to imitate a built-in class, IMO the built-in classes
> should continue to have rich interfaces.

It's still unclear to me exactly when/why one would need
those modules to imitate a built-in class. Especially if the
main role of the module is to sort of remind you that you
don't need to implement all the built-in's methods. It seems
to me that the plasticity of Ruby already makes this easy
and clean. Obviously one needs to decide which methods to
implement, but I don't see that as very obscure.

Anyway -- as you said a few postings ago, this isn't a big deal
to implement in Ruby (a point which I think some of the Perl
tie discussion has obscured a bit) -- so have at it!


David

--

Christoph Rippel

unread,
Jan 9, 2001, 5:45:33 PM1/9/01
to
> -----Original Message-----
> From: Ben Tilly [mailto:ben_...@hotmail.com]
> Sent: Tuesday, January 09, 2001 06:18 AM
> To: ruby-talk ML
...
> One note. A good deal of Ruby's current library is
> designed after how Perl works. For scripting I think that
and probably the real reason behind the current
everything is either an 'Array or Hash' container
strategy ...
> this is an excellent choice. So even though it should be
> easy to imitate a built-in class, IMO the built-in classes
> should continue to have rich interfaces.

Christoph

0 new messages