From: John Johnson Date: 2003-05-30T21:22:10+09:00 Subject: Re: Iteration - last detection I may be over simplifiying, but Enumerable defines max, so couldn't you: a = {} a["a"] = "A" a["b"] = "B" a["c"] = "C" a.each { |key, val| print "#{key} = #{val}" if key === a.keys.max puts " and that's the last one" else puts end } Regards, JJ on 5/30/03 8:08 AM, Robert at bob.news@gmx.net wrote: > 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 >> > >