Lus tellers

Geplaatst door Michiel de Mare di, 29 aug 2006 03:54:00 GMT

Ik ben op een vreemde eigenschap in Ruby gestuit terwijl ik een loop counter probeerde te schrijven die niet geïnitialiseerd hoefde te worden.

i = 1 + (i || -1)

Het idee was dat de eerste keer de counter op 1 + -1 (==0) wordt gezet, en dat hij daarna met één verhoogd wordt. Maar toen bedacht ik dat dit niet werkt omdat de rechterkant eerst geëvalueerd wordt, en daarin i ongedefineerd is. Toch bleek dit te werken! bar geeft een foutmelding, maar bar = bar is wel geldig!

Vreemd, nietwaar?

Uiteindelijk bleek deze constructie niet te werken omdat hij in een block stond, zodat alle lokale variabelen uit scope raken aan het eind van een block.

Geplaatst in  | 3 reacties

Reacties

  1. Thijs van der Vossen zei 37 minuten later:

    Zie punt 4.3 van http://dev.rubycentral.com/faq/rubyfaq-4.html

  2. Michiel zei ongeveer 1 uur later:

    Aha! Dat was ik al weer helemaal vergeten.

    Wat ik eigenlijk wilde doen, is zoiets:

    list.with_index.map {|obj, index| ... }

    Dat kan zo:

    
    class Macro
      def initialize(t); @target = t; end
    
      def method_missing(meth, *args, &b)
        i = 0; 
        @target.send(meth, *args) {|x| i += 1; b.call(x,i-1)}
      end
    end
    
    class Array;
      def with_index; Macro.new self end
    end
    
  3. Thijs van der Vossen zei ongeveer 7 uur later:

    list.zip((0…list.length).to_a).map{ |o, i| puts ”#{i}: #{o}”}

(Laat url/e-mail achter »)

   Voorvertoning