Accessing a block's "receiver"

I was writing the following piece of code:

class String
def title_case(exceptions = [])
exclude = %w(a an the some and but or not for) + exceptions
split(/\b/).map_with_index {|w, i|
(exclude.include?(w) or
((i>1) && self[i-1] == “’” && self[i-2] =~ /w/)) ? w : w.capitalize
}.join.capitalize
end
end

when I realised that ‘self’ was not what I wanted, since it belongs to
the block definition scope. What I want is a way to get at the anonymous
self.split object to which the block is passed - i.e. a variable recv,
analogous to self, that gets set when a block is yielded to or a proc is
called.

As it stands, I have to introduce a separate variable, b, just so I can
say b = split(/\b); b.map_with_index {|w,i| … b[i] …} - this
feels like it should be unnecessary. What would be nice would be for
’yield args’ to implicitly be ‘yield self, args’, proc.call(*args) be
proc.call(self, args) and {|args| …} be {|recv, args| }.

Good idea? Bad idea? Disastrously bad idea? :slight_smile:

martin

Hi –

Martin DeMello martindemello@yahoo.com wrote in message news:KuYR9.86244$na.2370717@news2.calgary.shaw.ca

I was writing the following piece of code:

class String
def title_case(exceptions = )
exclude = %w(a an the some and but or not for) + exceptions
split(/\b/).map_with_index {|w, i|
(exclude.include?(w) or
((i>1) && self[i-1] == “'” && self[i-2] =~ /w/)) ? w : w.capitalize
}.join.capitalize
end
end

when I realised that ‘self’ was not what I wanted, since it belongs to
the block definition scope. What I want is a way to get at the anonymous
self.split object to which the block is passed - i.e. a variable recv,
analogous to self, that gets set when a block is yielded to or a proc is
called.

As it stands, I have to introduce a separate variable, b, just so I can
say b = split(/\b); b.map_with_index {|w,i| … b[i] …} - this
feels like it should be unnecessary. What would be nice would be for
‘yield args’ to implicitly be ‘yield self, args’, proc.call(*args) be
proc.call(self, args) and {|args| …} be {|recv, args| }.

Good idea? Bad idea? Disastrously bad idea? :slight_smile:

Does “disaster” include causing all Ruby code to stop working? :slight_smile:

Even leaving that aside, it doesn’t appeal to me. In exchange for a few cases
where you’d have to refactor (as above), you’d have thousands of cases
where you’d see:

obj.meth {|discard_me,a,b| …}

You could use instance_eval:

class String
def title_case(exclude = )
exclude.concat(%w(a an the some and but or not for))
split(/\b/).instance_eval {
map_with_index {|w, i|
(exclude.include?(w) or
((i>1) && self[i-1] == “'” && self[i-2] =~ /w/)) ? w : w.capitalize }
}.join
end
end

(Includes some left-over tweakings from playing around – just ignore
those :slight_smile:

David Black
dblack@candle.superlink.net

(posting from Google… soon to resubscribe to ruby-talk after being out
of town)

Does “disaster” include causing all Ruby code to stop working? :slight_smile:

Even leaving that aside, it doesn’t appeal to me. In exchange for a
few cases where you’d have to refactor (as above), you’d have
thousands of cases where you’d see:

obj.meth {|discard_me,a,b| …}

No, I meant an implicit recv (much as method calls don’t need an
explicit self). It’d break anything that used ‘recv’ as a variable name,
but everything else would continue to work transparently - they just
wouldn’t use the passed in recv.

You could use instance_eval:

That’s neat :slight_smile: Never thought of instance_eval.

martin

···

David Alan Black dblack@candle.superlink.net wrote: