Proc {} vs. Method#to_proc

“Kent Dahl” kentda@stud.ntnu.no schrieb im Newsbeitrag
news:3E56057A.77E22E0C@stud.ntnu.no…
[snip]

class Entry < Array
end
class MyHash
def initialize
@entries =
end
def
# strange hashing magic
end
def insert(key, value)
e = Entry.new
e << key
e << value
@entries << e
end
def each
@entries.each{|e| yield e}
end
end
m = MyHash.new
m.insert( “a”, “Alfa” )
m.insert( “b”, “Beta” )
m.each{|e| p e.type } # I care about entry metadata
m.each{|k,v| p k.type, v.type } # I don’t, gimme the content!
[snip]

Your example was about what happens to a single yield argument (“yield e”)
but as I see it I was talking about the different behavior of yield with
multiple values. I see an asymmetry between these cases where my block has
too few parameters:

irb(main):067:0* def foo2() yield 1,2; end
nil
irb(main):068:0> foo2{|a| p a}
[1, 2]
nil
irb(main):069:0> foo2{|a| p a}
[1, 2]
nil
irb(main):070:0> foo2{|a,| p a}
1
nil
irb(main):071:0>
irb(main):072:0
def foo3() yield 1,2,3; end
nil
irb(main):073:0> foo3{|a,b| p a, b}
1
2
nil
irb(main):074:0>

It’s the question whether line 68 should behave like 69 or 70. I’d prefer
70 because that is IMHO more consistent with line 73. Read “too few
parameters => distribute arguments over parameters and forget the rest”.
I’d prefer to write *a if I want to get all parameters than to write a, to
make sure I get only the first.

I wouldn’t mandate a language change though, since I guess this would break
too much existing code. It is just that this asymmetry confused me. But I
think, I got it now. :slight_smile:

But I guess it’s a lot a matter of taste.

Aye, and like fine wine, its an aquired one at that :slight_smile:

Yup. :slight_smile:

Disclaimer: I hope the above makes somewhat sense and isn’t too wrong in
parts. I haven’t slept too well so my head is everywhere.

Thanks again for your time.

Regards

robert

“Martin DeMello” martindemello@yahoo.com schrieb im Newsbeitrag
news:J%m6a.316187$Yo4.11888543@news1.calgary.shaw.ca…

“Martin DeMello” martindemello@yahoo.com schrieb im Newsbeitrag

Tangentially, is the following code safe:

def initialize(*factors)
@factors = factors
@filters =
@factors.select {|i| i.is_a?(Proc)}.each {|fn|
(@filters[(fn.arity.abs) -1] ||= ) << fn
# ( a kludge to get around the fact that {|x|}.arity = -1 )
}
@factors.reject!{|i| i.is_a?(Proc)}
@dim = @factors.length
end

assuming the blocks in @factors are guaranteed not to have *d
arguments?
Or is there some insidious corner case I’m missing?

I’m not sure whether I understand where you’re up to. I wonder why you
substract 1 from the abs(arity).

To have the array start indexing from 0 :slight_smile: The bane of array programmers
for generations now.

Ah, I see. As long as you can make sure that nobody sends you a block with
arity = 0…

The abs() is the kludge I was referring to - it’s
there solely to take care of the arity=-1 case.

Yes, of course.

And another tip aside: move the reject! above then @factors.select.
Then
you can omit the select and gain a bit performance. :slight_smile:

Sadly, reject! returns the array, not the rejected elements. I’m trying
to separate the array into procs and non-procs (what I ought to do is to
use partition, now that it’s in 1.8).

Oops, yes I overlooked that there is no “!”: I thought you wanted to remove
all non procs but in effect you do a partition. sorry for the confusion.

Regards

robert
···

Robert Klemme bob.news@gmx.net wrote: