This one short-circuits, evaluating the left operand when the
flip-flop is false and the right operand when true:

  class FlipFlop
    attr_accessor :flip

    @@FF = Hash.new {|h,k| h[k] = FlipFlop.new}

    def FlipFlop.[](id)
      @@FF[id]
    end

    def initialize
      @flip = Proc.new if block_given?
      @in_range = false
      @num = 0
    end

    def flop(like=:awk)
      if @in_range
        @in_range = ! yield
      else
        @in_range = @flip[] or return
        @in_range = ! yield if like == :awk
      end
      @num = String === @num ? 1 : @in_range ? @num + 1 : "#{@num + 1}E0"
    end

    def flop!(&b)
      flop(:sed, &b)
    end
  end

  module Kernel
    def flip(id=caller[0])
      FlipFlop[id].flip = Proc.new
      FlipFlop[id]
    end
  end

  puts ".. and ..."
  a = (1..10).map {|i| i==3 .. (i+=0.5 and i==6.5) ? i : -i}
  b = (1..10).map {|i| i==3 ... (i+=0.5 and i==6.5) ? i : -i}
  p a, b

  puts "#flip#flop and #flip#flop!"
  a = (1..10).map {|i| flip {i==3}.flop {i+=0.5 and i==6.5} ? i : -i}
  b = (1..10).map {|i| flip {i==3}.flop! {i+=0.5 and i==6.5} ? i : -i}
  p a, b

Internal state is maintained using #caller info, so an explicit :label
is required if there is more one #flip#flop per line:

  a = (1..10).select do |i|
    flip(:x) {i==3}.flop {i==7} and flip(:y) {i==5}.flop {i==9}
  end

Maybe useful, maybe not, but returns a sequence number, like Perl:

  ('a'..'z').each {|x|
    i = flip {x=~/[ep]/}.flop {x=~/[iw]/}
    puts "#{x}: #{i.inspect}"
  }

Outputs:

  a: nil
  b: nil
  c: nil
  d: nil
  e: 1
  f: 2
  g: 3
  h: 4
  i: "5E0"
  j: nil
  k: nil
  l: nil
  m: nil
  n: nil
  o: nil
  p: 1
  q: 2
  r: 3
  s: 4
  t: 5
  u: 6
  v: 7
  w: "8E0"
  x: nil
  y: nil
  z: nil