From: dblack@... (David Alan Black) Date: 2003-01-06T09:59:12+09:00 Subject: Re: Accessing a block's "receiver" Hi -- Martin DeMello wrote in message news:... > 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? :) Does "disaster" include causing all Ruby code to stop working? :-) 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 :-) David Black dblack@candle.superlink.net (posting from Google... soon to resubscribe to ruby-talk after being out of town)