From: Robert Date: 2003-05-30T21:08:29+09:00 Subject: Re: Iteration - last detection Detecting if the first element might in some circumstances server the same purpose and it's easy done without Thread tricks: def print_format(enum) first = true str = "[" enum.each do |e| if first first = false else str << ", " end str << e.to_s end str << "]" str end a=[10, 30, "foo"] puts print_format(a) robert "Carlos" schrieb im Newsbeitrag news:20030530113250.GB1403@quovadis.com.ar... > > Is there any built in functionality for iteration that will allow me to > > detect when I am on the last element? This would not be hard for an Array, > > using array.length, but what about a Hash? How would I know when I am at > > the last element? > > Here is a module that implements it, but you should include it in every > class where you want #each to behave that way :-/. (And some #each-like > methods (for example, String#each_byte, don't work at all...) > > oe.rb: > #!/usr/bin/ruby > > class Object > def last? > Thread.current.last_iteration? > end > private :last? > end > > class Thread > def last_iteration? > @__last_iteration__ > end > end > > module EachWithLast > def EachWithLast.append_features(klass) > old_each="each_"+rand(10000).to_s+Time.now.usec.to_s > klass.class_eval <<-FINISH > alias_method :#{old_each}, :each > > def each(*a,&b) > element = nil > flag = false > #{old_each}(*a) { |e| > Thread.current.instance_eval { > @__last_iteration__=false > } > b.call element if flag > flag=true > element=e > } > if flag > Thread.current.instance_eval { > @__last_iteration__=true > } > b.call element > Thread.current.instance_eval { > @__last_iteration__=false > } > end > end > FINISH > end > end > > class Array; include EachWithLast end > > a = [1,2,3,4,5].select {|e| last? } > p a # => [5] > > class Range; include EachWithLast end > class String; include EachWithLast end > > for i in 1..10 > print "and the last is: " if last? > print i > "ds\njkd\njsk\nsd".each { |l| puts " - the last line is #{l}" if last? } > end > > class File; include EachWithLast end > File.open("oe.rb") { |f| > count = 0 > f.each { |line| > count += line.length > print "last line: #{line}" if last? > } > print "total chars: #{count}\n" > } > #THE LAST LINE >