Deciding between ruby and python

Hi,

···

In message “Re: deciding between ruby and python” on 04/04/04, Dan Doel djd15@po.cwru.edu writes:

At least, that’s how I’ve seen it described (and a quick check reveals that
join calls #to_s, never #to_str, and when I redefine #to_s, it can throw an
exception, just like Python would).

Maybe “join” should call “to_str” instead of “to_s” in the future.

						matz.

Ah, yes. Upon going back and reading I had it backwards. Serves me right for
trying to rely on my memory alone.

I’m conflicted in my opinions. On the one hand, perhaps it’d be good for #join
to only use #to_str to convert, since that means objects are allowed to be
auto-converted, and that would be appropriate for duck typing (that is, the
object is saying it acts like a string through this conversion). Calling #to_s
doesn’t mean the object is “supposed” to be interchangeable with a string.

On the other hand, we could say #join takes an array of objects with the
method #to_s, and that’d be appropriate as well. Really, I don’t see the
danger of this, since when I #join, I want a string. I doubt having it throw
an exception on non-string-interoperable objects will catch real errors on a
regular basis. The argument that it will seems like a red herring to me.

Luckily, my opinion doesn’t matter at all. :slight_smile:

  • Dan

#each is not just a for loop. #each is the embodiment of Ruby’s
ability to provide arbitrary abstraction layers using blocks.
Functionally, it may be a for loop, but suggesting they’re equivalent
is missing an important point.

Python has a for loop, as you say. Ruby doesn’t. Its ‘for’ keyword
is sugar for #each, and you’ll find it’s not used often. Where is
Python’s #each_with_index, and #select? Where is Python’s equivalent
of

File.open(‘/tmp/xyz’, ‘w’) do |f|
f.write(‘blah’)
end # file is closed automatically

Where is Python’s

“Hello world”.gsub(/(w\w+)/) { |match|
match.upcase
}

produces “Hello WORLD”

Generators do not provide Ruby’s ‘yield’ functionality. They provide
“expanded for loops”, which require explicit invocation, which
(despite the zen) is not in this case a good thing.

Possibly Python does provide all this, or a way to get it. Just as
you are guilty of approaching Ruby from a Python frame of reference, I
am guilty in the opposite direction.

But Ruby’s blocks are far superior to Python’s generators, IMO. They
are not a superficial feature that could just be tacked on to the
langauge to make everyone happy. Ruby would suck without them :slight_smile:

Blocks, and their pervasiveness in the Ruby language, provide an
incredibly elegant way of writing high-level code while providing
low-level directives. It’s the best “separation of concerns” I’ve
seen in any language.

Cheers,
Gavin

PS. Ruby has generators as well, in the standard library (implemented
in Ruby, not in the interpreter).

···

On Sunday, April 4, 2004, 11:14:19 PM, Ville wrote:

> I'm not the poster of that opinion, but I imagine he was
> referring to things like #each and #inject and the Enumerable
> module. I don't know Python, so I don't know what the
> analogues to these are, or if it has them at all.  Perhaps
> whenever he looked at Python, it didn't.

#each is just a for loop (at least the #each usages I’ve seen
here). Python has always had it, but but it didn’t probably have
generators, which provide ‘yield’ functionality. Well, it has now.

Bad idea, IMO. “join” is designed for returning a string. It
therefore has the right to create strings as necessary for this
purpose.

“join” is similar to “puts” in this regard.

And to consider another angle: join is a generally useful method.
#to_str is only implemented in a small set of classes. “join” would
become a lot less useful if you implemented that change.

David Black’s comments on this elsewhere were also illuminating.

Cheers,
Gavin

···

On Monday, April 5, 2004, 12:09:58 AM, Yukihiro wrote:

Hi,

In message “Re: deciding between ruby and python” > on 04/04/04, Dan Doel djd15@po.cwru.edu writes:

At least, that’s how I’ve seen it described (and a quick check reveals that
join calls #to_s, never #to_str, and when I redefine #to_s, it can throw an
exception, just like Python would).

Maybe “join” should call “to_str” instead of “to_s” in the future.

HI –

Ah, yes. Upon going back and reading I had it backwards. Serves me right for
trying to rely on my memory alone.

I’m conflicted in my opinions. On the one hand, perhaps it’d be good
for #join to only use #to_str to convert, since that means objects
are allowed to be auto-converted, and that would be appropriate for
duck typing (that is, the object is saying it acts like a string
through this conversion). Calling #to_s doesn’t mean the object is
“supposed” to be interchangeable with a string.

I think there’s a difference between an object acting like a string
and an object saying it acts like a string. (Does that make any
sense?) I’ve always understood #to_str as mainly for cases where an
object is acted upon directly – like:

“x” + obj # obj had better be able to masquerade as a String

rather than a case like #join where, so to speak, the objects (the
array elements) are asked for string representations of themselves,
rather than for themselves-being-Strings.

That said, I’ve also never been 100% sure why String#+ couldn’t be
more tolerant – that is, allow objects to present their #to_s
representations, rather than insisting that they either be Strings or
have a #to_str method. The whole concept of “wanting a String object”
and having a mechanism that makes an object appear that way strikes me
as uncharacteristically classname-centric for Ruby. Then again,
perhaps there’s a certain amount of classname-based things that have
to happen in order to bootstrap the lovely object-centric programming
space we know and love.

David

···

On Sun, 4 Apr 2004, Dan Doel wrote:


David A. Black
dblack@wobblini.net

#each is not just a for loop. #each is the embodiment of Ruby’s
ability to provide arbitrary abstraction layers using blocks.
Functionally, it may be a for loop, but suggesting they’re equivalent
is missing an important point.

As of current python, you have equivalent mechanics for yield as an
iterator thing.
each_with_index is enumerate(iterable).
Select is ifilter(), and there is imap() and there are equivalents for
many other things.

Ruby iterator/blocks and python iterators/generator are very different
approaches that yield similar results somehow, but both are really
valuable and I don’tn think one is inherently better than the other.

Obviously, in ruby there are blocks for everything cause ruby had them
since the beginning, see the gsub example.
But note that python has a re.finditer() that allows you to get an
iterable object with the match inside.

I love blocks as a useful lambda form and extension mechanism, say, I
love this:

def with(obj,&blk)
obj.instance_eval(&blk)
end
=> nil
with(mio=Object.clone) do
?> def f
print ‘foo’
end
end
=> nil
mio.f
foo=> nil

(dirty prototyping ruby :sunglasses:

but for what relates to iteration I believe python is getting ruby.

···

il Mon, 5 Apr 2004 02:42:16 +0900, Gavin Sinclair gsinclair@soyabean.com.au ha scritto::

Maybe “join” should call “to_str” instead of “to_s” in the future.

Bad idea, IMO. “join” is designed for returning a string. It
therefore has the right to create strings as necessary for this
purpose.
“join” is similar to “puts” in this regard.

Yeah, but it should be the objects decision whether it’s able to provide a meaningful
String version of itself.

I generally use to_s for debugging, or any situation when I need
to quickly ‘see’ the object - i.e. to_s provides a string
representation of itself for my benefit.
So 99% of my classes have a to_s method, but it’s typically a
list of its instance variables, for the very reason that puts calls it.

join or anything else that wants a string to work with should
ask the object to provide one, and to_str is there for that.

If I haven’t implemented that method I’m saying
“I’m not a String, and I’m not going to pretend to be one”.

And to consider another angle: join is a generally useful method.
#to_str is only implemented in a small set of classes. “join” would
become a lot less useful if you implemented that change.

I still reckon join should be meeting those classes halfway. it’s not their
job to keep join happy at the end of the day. Classes who want to
can easily ‘alias_method :to_str :to_s’, but only if they decide that makes
sense in their case.

···

On Monday, April 5, 2004, 12:09:58 AM, Yukihiro wrote:


A witty saying proves nothing, but saying something pointless gets
people’s attention.
Rasputin :: Jack of All Trades - Master of Nuns

Hi,

···

In message “Re: deciding between ruby and python” on 04/04/04, “David A. Black” dblack@wobblini.net writes:

That said, I’ve also never been 100% sure why String#+ couldn’t be
more tolerant – that is, allow objects to present their #to_s
representations, rather than insisting that they either be Strings or
have a #to_str method.

Pre 1.0 Ruby was very tolerant about types: 1 + “2” gave 3, and
“2” + 1 gave “21”.

But this tend to hide the type mismatch error, so that I had to follow
the “crash early” principle from Pragmatic Programmers.

						matz.

#each is not just a for loop. #each is the embodiment of Ruby’s
ability to provide arbitrary abstraction layers using blocks.
Functionally, it may be a for loop, but suggesting they’re equivalent
is missing an important point.

As of current python, you have equivalent mechanics for yield as an
iterator thing.
each_with_index is enumerate(iterable).
Select is ifilter(), and there is imap() and there are equivalents for
many other things.

It’s not equivalent. Ruby’s approach is more OO: you can chain
methods. What you present on Python’s side are functions. To combine
those in a meaningful way, I foresee list comprehensions :slight_smile: Or the
good old Perlish:

for s in uniq(sort(map(grep(…))))) :slight_smile:

Ruby iterator/blocks and python iterators/generator are very different
approaches that yield similar results somehow, but both are really
valuable and I don’t think one is inherently better than the other.

I argue that Ruby’s is better because it’s more general (provides
features beyond mere iteration), more OO (thus a better fit with the
language), and more high-level (see below). The different approaches
have different side-effects, and in terms of power and even
aesthetics, Ruby has nailed this one dead on.

Obviously, in ruby there are blocks for everything cause ruby had them
since the beginning, see the gsub example.
But note that python has a re.finditer() that allows you to get an
iterable object with the match inside.

I dislike being given iterable ojects for everything. That means
you’re doing explicit iteration, whereas Ruby gives you implicit
iteration. Implicit is definitely better than explicit in this case:
it gives you higher-level code without any sacrifice in power. It
removes swathes of boiler-plate code from the programmer’s view without any
loss of context, intention, or nuance. It puts the important code in
from of the programmer and the repetitive code in the background.

Don’t get me wrong, Python is a high-level language. But Ruby is a
very high-level language.

Cheers,
Gavin

···

On Monday, April 5, 2004, 7:24:18 AM, gabriele wrote:

il Mon, 5 Apr 2004 02:42:16 +0900, Gavin Sinclair > gsinclair@soyabean.com.au ha scritto::

Maybe “join” should call “to_str” instead of “to_s” in the future.

Bad idea, IMO. “join” is designed for returning a string. It
therefore has the right to create strings as necessary for this
purpose.
“join” is similar to “puts” in this regard.

Yeah, but it should be the objects decision whether it’s able to provide a meaningful
String version of itself.

I’m probably covering the same ground as DAB here, but there’s a big
difference between a String version of itself and a String
representation of itself. #to_str is aimed at the former, and #to_s
is aimed at the latter.

I believe that #join is interested in String representations, not
String versions, of objects.

And if you, as the high-level programmer, want a different
representation, there’s always

puts objects.map { |o| “… #{o.attribute} …” }.join(", ")

In this light, think of

puts objects.join(", ")

as using the default string representation of the objects.

I generally use to_s for debugging, or any situation when I need
to quickly ‘see’ the object - i.e. to_s provides a string
representation of itself for my benefit.

I think you should be using #inspect here. That’s intended for
debugging, #to_s is not. There’s definitely a reason for having both
methods, and I think that’s it.

So 99% of my classes have a to_s method, but it’s typically a
list of its instance variables, for the very reason that puts calls it.

join or anything else that wants a string to work with should
ask the object to provide one, and to_str is there for that.

If I haven’t implemented that method I’m saying
“I’m not a String, and I’m not going to pretend to be one”.

That’s not consistent with my understanding of the intentions of #to_s
and #to_str. These methods (and #to_i/#to_int, etc.) have been a
reliable source of confusion for quite a while now. I hope that they
get addressed in Pickaxe II or another educational resource.

Cheers,
Gavin

···

On Monday, April 5, 2004, 8:44:59 AM, Dick wrote:

On Monday, April 5, 2004, 12:09:58 AM, Yukihiro wrote:

Just a as we are on the subject. Should Ojbect#to_s return self.to_str
if it is defined instead of the default value?

EX:
class Toto; end
Toto.new.to_s # => “#Toto:0x31f7ac

class Toto; def to_str; “toto”; end; end
Toto.new.to_s

The last statement today returns "<#Toto:…>. Should it return “toto”
instead? Meaning, shouldn’t the string representation of an object
(returned by #to_s) be the same as it String masqueraded behavior? Of
course, nothing prevents you from to define to_s as to_str if you
want… Just wondering about what default behavior makes the most
sense.

Guillaume.

···

Le 4 avr. 04, à 10:18, Yukihiro Matsumoto a écrit :

Hi,

In message “Re: deciding between ruby and python” > on 04/04/04, “David A. Black” dblack@wobblini.net writes:

That said, I’ve also never been 100% sure why String#+ couldn’t be
more tolerant – that is, allow objects to present their #to_s
representations, rather than insisting that they either be Strings or
have a #to_str method.

Pre 1.0 Ruby was very tolerant about types: 1 + “2” gave 3, and
“2” + 1 gave “21”.

But this tend to hide the type mismatch error, so that I had to follow
the “crash early” principle from Pragmatic Programmers.

  					matz.

It’s not equivalent. Ruby’s approach is more OO: you can chain
methods. What you present on Python’s side are functions. To combine
those in a meaningful way, I foresee list comprehensions :slight_smile: Or the
good old Perlish:

for s in uniq(sort(map(grep(…))))) :slight_smile:

ok, I can agree, cause I like consistency, but I think you can agree
with me that having map(func,itr) or itr.map(func) does not really add
anything…

Ruby iterator/blocks and python iterators/generator are very different
approaches that yield similar results somehow, but both are really
valuable and I don’t think one is inherently better than the other.

I argue that Ruby’s is better because it’s more general (provides
features beyond mere iteration),

it’s not more general. It’s general in a different way.
Python with the introduction of generators gained some of the power we
got with call/cc cause they’re actually coroutines (or
semi-coroutines). You can use them as state machines. You can build
thread out of generators.

some things you do with esplicit iterators can’t be done with implicit
ones, say:
We have Enumerable#zip(anEnumerable), while python has
izip(anIterable,anIterable).

In ruby you’re forced to build a huge array any time you use zip, whle
in python you can delay the creation of the yielded pair till they’re
actually useful. You can’t use zip() with Prime.new in ruby, but you
can in python. Well you can in ruby cause we have call/cc :slight_smile:

In the end I just think that there is reason for having generator.rb
in the core lib :slight_smile:

···

il Mon, 5 Apr 2004 08:39:32 +0900, Gavin Sinclair gsinclair@soyabean.com.au ha scritto::

(Yes, I know I’m really overstaying my welcome in this ng, just
"trolling" a 0.02E more)

>> As of current python, you have equivalent mechanics for yield
>> as an iterator thing.  each_with_index is enumerate(iterable).
>> Select is ifilter(), and there is imap() and there are
>> equivalents for many other things.

> It's not equivalent.  Ruby's approach is more OO: you
> can chain methods.  What you present on Python's side
> are functions.  To combine those in a meaningful way, I
> foresee list comprehensions :) Or the good old Perlish:

> for s in uniq(sort(map(grep(........)))))  :)

And truly, I don’t see anything wrong with that code. It’s not
’perlish’, it’s the plain old functional way of doing things. It’s
chaining just like with method calls.

>> Ruby iterator/blocks and python iterators/generator are very
>> different approaches that yield similar results somehow, but
>> both are really valuable and I don't think one is inherently
>> better than the other.

> I argue that Ruby's is better because it's more general
> (provides features beyond mere iteration), more OO (thus
> a better fit with the language), and more high-level
> (see below).  The different approaches

Blocks provide iteration and anonymous functions. Both exist in
Python. And if the needs of your anonymous function exceed what lambda
provides, you can use what I call big L notation:

def L(matchobj):
return matchobj.group(0).upper()

res = re.sub(‘u|a’, L, ‘huijaahuijaa’)

> I dislike being given iterable ojects for everything.
> That means you're doing explicit iteration, whereas Ruby
> gives you implicit iteration.  Implicit is definitely
> better than explicit in this case: it gives you
> higher-level code without any sacrifice in power.  It

Perhaps some of us like to do our iteration explicitly. I don’t think
there is any syntactic overhead, and the for loop reads
better. Counterexamples welcome.

Obviously we can do #each too:

def L(x):
print x
return x*2

map(L, [1,2,3])

But plain old for loop is more convenient, esp. if you don’t need to
generate a result list in the process.

> Don't get me wrong, Python is a high-level language.
> But Ruby is a very high-level language.

Oh, please. That wouldn’t be true even if Ruby afficiandos kept
repeating it 10 times a day (it could even become the new “Python OO
is a hack”). Ruby and Python are pretty much exactly on the same level
abstraction-wise. Ruby is higher level than Python in the sense Perl
is higher level than Python, i.e. it provides some “conveniences” of
questionable utility like regexps in language syntax and multiple
methods doing the same thing.

···


Ville Vainio http://tinyurl.com/2prnb

Hi,

···

In message “Re: deciding between ruby and python” on 04/04/05, Guillaume Marcais guslist@free.fr writes:

Just a as we are on the subject. Should Ojbect#to_s return self.to_str
if it is defined instead of the default value?

I encourage defining “to_str” along with string methods, i.e. by
defining “to_str”, I expect the object to be a duck quacks like
strings. In that sense, you have to think before defining “to_str”,
more than it seems, even though your proposal makes sense.

						matz.

Perhaps some of us like to do our iteration explicitly. I don’t think
there is any syntactic overhead, and the for loop reads
better. Counterexamples welcome.

Obviously we can do #each too:

def L(x):
print x
return x*2

map(L, [1,2,3])

(reverse (map (lambda (x) (begin (display x) (* x 2)))
(map (lambda (x) (+ x 2)) (list 1 2 3))))

[1,2,3].each {|x| x+2}.each {|x| print x;return x*2}.reverse

or if you prefer

[1,2,3].each {|x| x+2}.each do |x|
print x
x*2
end.reverse

(yes these are contrived but I have had many situations where something
like this was necessary)

I don’t know alot of about python, but from what I have gathered it
appears it follows the lisp style of functions, to a certain degree.
However, I found the ruby reordering much more readable, and an
equivalent reordering in another language is not feasable without a
yield syntax, and everything returning something. “Do this, then this,
then this”, seems far more readable then by evaluating inside out. In
addition, passing the lambda block to the map always caused readability
problems for me. If you nested a couple of maps it became difficult to
read which parts were the logic of the map and which part was the list.
Addmittidly some of this may be from the uniformness of lisp/scheme
code that comes from the paranthesis, but this syntax still suffers from
a basic difficulty. If I embed the logic at the point of call with a
lambda block I lose readability because it makes it difficult to find
what is being processed. Or, if I put the logic in another function,
the logic is seperated, forcing me to look elsewhere to see what the map
is doing. That’s what I love about ruby’s yield syntax combined with
objects, they give me a chaining that I find far more readable then
nested calls.

But plain old for loop is more convenient, esp. if you don’t need to
generate a result list in the process.

a = [1,2,3]
a = for x in a
print x
x + 2
end.reverse

In ruby you don’t need to choose between map and for if you want the
result list, you can do whichever pleases you the most.

But I suppose that is reaon to choose what language you prefer,
whichever pleases you the most,

Charles Comstock

Hi --

Obviously we can do #each too:

def L(x):
    print x
    return x*2

map(L, [1,2,3])

That looks like #map rather than #each.

But plain old for loop is more convenient, esp. if you don't need to
generate a result list in the process.

#each doesn't generate a result list. It returns the receiver.

David

···

On Mon, 5 Apr 2004, Ville Vainio wrote:

--
David A. Black
dblack@wobblini.net

(Yes, I know I’m really overstaying my welcome in this ng, just
“trolling” a 0.02E more)

I don’t mind. You post intelligently, and although a lot of this
stuff is pretty subjective, I think there are yet more objective
observations to be teased out.

> for s in uniq(sort(map(grep(........)))))  :)

And truly, I don’t see anything wrong with that code. It’s not
‘perlish’, it’s the plain old functional way of doing things. It’s
chaining just like with method calls.

So it’s the functional way of doing things. I’ve got nothing against
that, but I’m not interested in it. I (much) prefer Ruby’s OO style.

>> Ruby iterator/blocks and python iterators/generator are very
>> different approaches that yield similar results somehow, but
>> both are really valuable and I don't think one is inherently
>> better than the other.
> I argue that Ruby's is better because it's more general
> (provides features beyond mere iteration), more OO (thus
> a better fit with the language), and more high-level
> (see below).  The different approaches

Blocks provide iteration and anonymous functions. Both exist in
Python. And if the needs of your anonymous function exceed what lambda
provides, you can use what I call big L notation:

def L(matchobj):
return matchobj.group(0).upper()

res = re.sub(‘u|a’, L, ‘huijaahuijaa’)

That’s a poor man’s substitute. Seriously. It means you have to name
everything you’re doing, and pollute the function namespace for no
good reason
. Yes, you can “do it”, but it’s ugly in comparison.

And there is an insurmountable limitation (I think):

Count the characters, words, and lines in the given string.

def count(str)
chars = words = lines = 0
str.each do |line|
chars += line.chomp.length
words += line.split
lines += 1
end
return [chars, words, lines]
end

Can you provide an implementation in the same style in Python? It’s
not that I don’t believe Python can count characters, lines and words
in a string. But I don’t believe it can carry outside state into its
“substitute for blocks”.

What about this example, demonstrating various database capabilities?

require “dbi”

Connection: the database connection is automatically released at

the end of the block, including if there is an exception therein.

DBI.connect(conn_str, user, passwd) do |dbi|

# Prepared statement: the resource is automatically freed at the
# end of the block.

total_distance = 0
dbi.prepare("SELECT road_distance from MAP_INFO where CITY1 = ?
             and CITY2 = ?") do |sth|
  sth.select("Sydney", "Melbourne") do |row|
    total_distance += row['distance'].to_i
  end
  sth.select("Melbourne", "Adelaide") do |row|
    total_distance += row['distance'].to_i
  end
end
puts "Road distance from Sydney to Adelaide via Melbourne is #{total_distance} km."

# Transaction support: any exception in this block will cause a
# "ROLLBACK".  If all is fine, a "COMMIT" is performed at the end.

dbi.transaction do |dbi|
  dbi.do("UPDATE bank_account SET balance = balance - 50 where name = 'alice'")
  dbi.do("UPDATE bank_account SET balance = balance + 50 where name = 'bob'")
end

end

I’d like to see the same program written in Python. I don’t know the
Python database interface, but I expect it would need to have explicit
exception handling. There would also be no automatic releasing of
resources.

I could be very wrong. But assuming I am correct, then the above
program demonstrates Ruby operating at a higher level of abstraction
than Python is capable of. All the yucky stuff like resource
management and transactions are taken care of by the library, not in
the top-level code. That is a perfect demonstration of “higher level
programming”.

That is my frame of reference when it comes to high-level programming.

> Don't get me wrong, Python is a high-level language.
> But Ruby is a very high-level language.

Oh, please. That wouldn’t be true even if Ruby afficiandos kept
repeating it 10 times a day (it could even become the new “Python OO
is a hack”). Ruby and Python are pretty much exactly on the same level
abstraction-wise. Ruby is higher level than Python in the sense Perl
is higher level than Python, i.e. it provides some “conveniences” of
questionable utility like regexps in language syntax and multiple
methods doing the same thing.

It is true, and a Python fan denying it 10 times a day doesn’t make it
false.

To prove me wrong, please present your best effort at translating the
database programming example above into Python. Of course, you may
disagree with my frame of reference instead, but I think that’s pretty
good.

Cheers,
Gavin

P.S. Let me restate that my knowledge of Python is very small compared
to yours, and I am happy to learn more about it. And at the end of
the day, if (when) we agree to disagree, I won’t be claiming that this
discussion has any real significance. It’s just interesting while it
lasts. I’m not a zealot; just keen on understanding the finer points
of life and/or computer programming :slight_smile:

···

On Monday, April 5, 2004, 5:04:18 PM, Ville wrote:

Why cannot we have attribute access of the object from anywhere in the program by sennding a message @attribute

class Example
def initialize
@number = '1.0’
end
end

e = Example.new
print e.@number => should print 1.0

rolo

In article jtt1709r6qpjqoft5gtl6gooeb34rnuevt@4ax.com,
: In ruby you’re forced to build a huge array any time you use zip, whle
: in python you can delay the creation of the yielded pair till they’re
: actually useful.

Nope.

yep
just look at you own output.
Now, if you’re not convinced try this:

def infinity
end
=> nil
require ‘mathn’
=> true
p=Prime.new
=> #<Prime:0x2b43048 @primes=, @seed=1, @counts=>
for i in [1,2,3].zip(p)
p i
end
TypeError: cannot convert Prime into Array
from (irb):5:in `zip’
from (irb):5
p.kind_of?Enumerable
=> true

guess why you can’t use a prime? because you can’t pause the yielding.
You’re forced to use the whole number of Prime number that are
actually… infinite.
So, you discover that you can’t zip it cause zip calls to_ary.

lazy generators allows you to use just one element at a time, so zip
can be used for any kind of enumerable.

It’s those blocks and yield again! Aren’t they great? Stick a block
after a zip and instead of building a great big array, it yields pairs
for you to do what you want with.

yes, after it constructed one big array:)

···

il Wed, 07 Apr 2004 05:35:39 GMT, dagbrown@LART.ca (Dave Brown) ha scritto::

gabriele renzi surrender_it@remove.yahoo.it wrote:

I’d really like to understand what you mean, here. In your first sentence,
did you mean to say “I expect the object to be a duck that quacks like
strings?” If so, what does it mean to quack like a string? If not, what were
you really trying to say?

Thanks,
Dave

···

In article 1081124063.259819.9185.nullmailer@picachu.netlab.jp, Yukihiro Matsumoto wrote:

Hi,

In message “Re: deciding between ruby and python” > on 04/04/05, Guillaume Marcais guslist@free.fr writes:

Just a as we are on the subject. Should Ojbect#to_s return self.to_str
if it is defined instead of the default value?

I encourage defining “to_str” along with string methods, i.e. by
defining “to_str”, I expect the object to be a duck quacks like
strings. In that sense, you have to think before defining “to_str”,
more than it seems, even though your proposal makes sense.


…:[ dave benjamin: ramen/[sp00] -:- spoomusic.com -:- ramenfest.com ]:.
: please talk to your son or daughter about parametric polymorphism. :