Comment on this RCR (edit wiki page) | RCRchive home

RCR 243: Add a basic iterator method to Object

submitted by dzsekijo on Sun Apr 11 2004 11:54:08 PM -0700

Status: withdrawn


Abstract

It would be nice if all objects had a basic iterator method, say passme, such that foo.passme would pass the value of foo to the block after foo.

Problem

One may think that the above can be achieved easily (for personal usage) -- one just puts the following into her/his code:

class Object
def passme; yield(self); end
end

but it's *not* acceptable as Object is the mother class of all classes, modifying it is extremely prone to name collisions unless the change is declared to be a part of the language. (Eg., I had the name pass in my mind for this method, but then I checked out that Thread already has such...)

Proposal

The class Object should have a method defined as follows:

def passme
yield(self)
end

(the name of the method might be different, of course; the most intutive (but maybe the most confusing as well) would be calling it yield as well...)

Analysis

Imagine the following: the (top-level) method (aka. "ruby function") bar should be applied to foo.massaged.by.methods ...
currently possible solutions:

Implementation

See above; it should be easy even if done in C

I don't understand what you propose. Your Problem describes the solution, but not the problem. What is it you are trying to solve?

-- Simon Strandgaard


The problem section explains why I think that the cited obvious three-liner hack which can be used by anyone is in fact *not* a solution (to the need of having this feature). I wouldn't feel easy to distribute code which modifies Object, as such a thing may be in conflict with other people's methods (in some arbitrary class). If Object had such a method *officially*, other people would know about it and they would avoid (re)defining it accidentally.

I personally treat the ruby iterator/block concept as a high-level, extended, bidirectional generalization of Unix shell pipes, and it would be cool if any object would have the right to write into this "pipe" but maybe this approach is just my personal perversion :) Btw, String has such a method already (String#each). I don't see any specific in String which would give a reason to make it an exception in this aspect.

dzsekijo


I'm not sure that this would require a new method like that. I have run across your situation many times, but I just just #instance_eval; it's more flexible, too, since you can use the internal methods without calling them on an object. A quick demo:


irb(main):000:0> "1+2+3".instance_eval{eval self}.times{print "*"}
******=> 6
irb(main):001:0> [1,2,3,4].instance_eval{slice(0..0)+slice(2..3)}.each{|n|print n," "}
1 3 4 => [1, 3, 4]

I may however, have not thought of a situation where having a special method defined would be better than this. Comments?

--Mark


Hmm, the whole point of this RCR seems to be that dzsekijo doesn't like to use a method call like:
  result = foo(bar)
but instead prefers:
  result = bar.passme { |bar_again| foo(bar_again) }

This is a very strange reasoning. If I want to call the foo method on the argument bar to get a result, I should just do that. Why should I want to type a pretty long block with block variables, that additionaly obfuscates that the whole expression returns now the result of the foo method, that is called with another reference to bar, as the result of passme?

-- Florian Frank


Add comments here


Vote for this RCR

Strongly opposed [6]
Opposed [0]
Neutral [0]
In favor [0]
Strongly advocate [0]

Change the status of this RCR to:

accepted

rejected

withdrawn

-- To Mark:
Yes, the #instance_eval method is just what I speak of! I just skipped it by acccidet when I was browsing the methods of Object (due to the somewhat obscure wording, I think). Though the name of this method is a bit long to be corfortable if one would like to use it frequently, in priciple I have no reason to maintain this RCR. I withdraw it.

-- To Florian Frank:
IMHO the situation is a bit different if you replace bar with an expression of one and a half line length, and you use a one-letter block variable instead of bar_again. You seem to make fun of my RCR with your example showing my idea in action... But it's quite the same now.
-- dzsekijo


Add comments here

Back to RCRchive.


RCR Submission page and RCRchive powered by Ruby, Apache, RuWiki (modified), and RubLog