Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby is Magic: Flip-Flop

Ruby is Magic: Flip-Flop

After a very long break we finally did another Ruby is Magic at Cologne.rb. This time we went with arguably the most absurd feature in Ruby: The flip-flop operator. As usual the slides are in German and don't work well without the live performance ;-)

Copyright Notice: My Little Pony - Friendship is Magic is Property of Hasbro and The Hub.

Dirk Breuer

January 21, 2015
Tweet

More Decks by Dirk Breuer

Other Decks in Programming

Transcript

  1. Previously on Ruby is Magic (viele) Absurditäten und (etwas) Nützliches

    Verrückter Syntax Inkonsistenzen Kuriositäten
  2. Flip-Flop In scalar context, ".." returns a boolean value. The

    operator is bistable, like a flip-flop, and emulates the line-range (comma) operator of sed, awk, and various editors. Each ".." operator maintains its own boolean state, even across calls to a subroutine that contains it. It is false as long as its left operand is false. Once the left operand is true, the range operator stays true until the right operand is true, AFTER which the range operator becomes false again. It doesn't become false till the next time the range operator is evaluated. It can test the right operand and become false on the same evaluation it became true (as in awk), but it still returns true once. If you don't want it to test the right operand until the next evaluation, as in sed, just use three dots ("...") instead of two. In all other regards, "..." behaves just like ".." does. The right operand is not evaluated while the operator is in the "false" state, and the left operand is not evaluated while the operator is in the "true" state. The precedence is a little lower than || and &&. The value returned is either the empty string for false, or a sequence number (beginning with 1) for true. The sequence number is reset for each range encountered. The final sequence number in a range has the string "E0" appended to it, which doesn't affect its numeric value, but gives you something to search for if you want to exclude the endpoint. You can exclude the beginning point by waiting for the sequence number to be greater than 1. If either operand of scalar ".." is a constant expression, that operand is considered true if it is equal (==) to the current input line number (the $. variable).
  3. Quelle: http:/ /perldoc.perl.org/perlop.html#Range-Operators Flip-Flop In scalar context, ".." returns a

    boolean value. The operator is bistable, like a flip-flop, and emulates the line-range (comma) operator of sed, awk, and various editors. Each ".." operator maintains its own boolean state, even across calls to a subroutine that contains it. It is false as long as its left operand is false. Once the left operand is true, the range operator stays true until the right operand is true, AFTER which the range operator becomes false again. It doesn't become false till the next time the range operator is evaluated. It can test the right operand and become false on the same evaluation it became true (as in awk), but it still returns true once. If you don't want it to test the right operand until the next evaluation, as in sed, just use three dots ("...") instead of two. In all other regards, "..." behaves just like ".." does. The right operand is not evaluated while the operator is in the "false" state, and the left operand is not evaluated while the operator is in the "true" state. The precedence is a little lower than || and &&. The value returned is either the empty string for false, or a sequence number (beginning with 1) for true. The sequence number is reset for each range encountered. The final sequence number in a range has the string "E0" appended to it, which doesn't affect its numeric value, but gives you something to search for if you want to exclude the endpoint. You can exclude the beginning point by waiting for the sequence number to be greater than 1. If either operand of scalar ".." is a constant expression, that operand is considered true if it is equal (==) to the current input line number (the $. variable). Perl!
  4. DON’T KNOW IF REAL FEATURE DON’T KNOW IF REAL FEATURE

    OR JUST FORGOTTEN TO REMOVE OR JUST FORGOTTEN TO REMOVE
  5. x=1 false false (x == 2)..(x == 4) x=2 true

    false if: false #=> if: true #=> 2 Input
  6. x=1 false false (x == 2)..(x == 4) x=2 true

    false x=3 false false if: false #=> if: true #=> 2 if: true #=> 3 Input
  7. x=1 false false (x == 2)..(x == 4) x=2 true

    false x=3 false false x=4 false true if: false #=> if: true #=> 2 if: true #=> 3 if: true #=> 4 Input
  8. x=1 false false (x == 2)..(x == 4) x=2 true

    false x=3 false false x=4 false true x=5 false false if: false #=> if: true #=> 2 if: true #=> 3 if: true #=> 4 if: false #=> Input
  9. In electronics, a flip-flop or latch is a circuit that

    has two stable states and can be used to store state information. Quelle: https://de.wikipedia.org/wiki/Flipflop
  10. x=1 false false (x == 2)..(x == 4) x=2 true

    false x=3 nil false x=4 nil true x=5 false false if: false if: true if: true if: true if: false Input flip-flop State
  11. x=1 false false (x == 2)..(x == 4) x=2 true

    false x=3 nil false x=4 nil true x=5 false false if: false if: true if: true if: true if: false Input flip-flop State !
  12. x=1 false false (x == 2)..(x == 4) x=2 true

    false x=3 nil false x=4 nil true x=5 false false if: false if: true if: true if: true if: false Input flip-flop State ! " !
  13. x=1 false false (x == 2)..(x == 4) x=2 true

    false x=3 nil false x=4 nil true x=5 false false if: false if: true if: true if: true if: false Input flip-flop State ! " " !
  14. x=1 false false (x == 2)..(x == 4) x=2 true

    false x=3 nil false x=4 nil true x=5 false false if: false if: true if: true if: true if: false Input flip-flop State ! " " ! " !
  15. x=1 false false (x == 2)..(x == 4) x=2 true

    false x=3 nil false x=4 nil true x=5 false false if: false if: true if: true if: true if: false Input flip-flop State ! " " ! " ! !
  16. ★ Gebe die Zahl aus ★ Gebe 'Fizz' aus wenn

    Zahl durch 3 teilbar ★ Gebe 'Buzz' aus wenn Zahl durch 5 teilbar ★ Gebe 'FizzBuzz' aus wenn Zahl durch 3 und 5 teilbar
  17. a=b=c = nil # Initialisierung! ! (1..100).each do |num| fizz

    = true unless (a = !a) .. (a = !a) buzz = true unless (b = !b) ... !((c = !c) .. (c = !c)) ! print_it(num, fizz, buzz) end
  18. (a = !a)..(a = !a) a=… flip-flop State nil true

    false if: true " ! false nil true if: true " !
  19. (a = !a)..(a = !a) a=… flip-flop State nil true

    false if: true " ! false nil true if: true " ! true false nil if: false !
  20. (a = !a)..(a = !a) a=… flip-flop State nil true

    false if: true " ! false nil true if: true " ! true false nil if: false ! false true false if: true " !
  21. (a = !a)..(a = !a) a=… flip-flop State nil true

    false if: true " ! false nil true if: true " ! true false nil if: false ! false true false if: true " ! false nil true if: true " !
  22. (a = !a)..(a = !a) a=… flip-flop State nil true

    false if: true " ! false nil true if: true " ! true false nil if: false ! false true false if: true " ! false nil true if: true " ! true false nil if: false !
  23. a=b=c = nil # Initialisierung! ! (1..100).each do |num| fizz

    = true unless (a = !a) .. (a = !a) ! print_it(num, fizz, buzz) end ✔ buzz = true unless (b = !b) ... !((c = !c) .. (c = !c))
  24. buzz = true unless (b = !b) ... !((c =

    !c) .. (c = !c)) (a = !a) .. (a = !a) unless fizz_flipflop
  25. (b = !b)...(fizz_flipflop) b=… flip-flop State nil true nil if:

    true " ! true nil false true nil false if: true " if: true "
  26. (b = !b)...(fizz_flipflop) b=… flip-flop State nil true nil if:

    true " ! true nil false true nil false if: true " true nil true if: true " ! if: true "
  27. (b = !b)...(fizz_flipflop) b=… flip-flop State nil true nil if:

    true " ! true nil false true nil false if: true " true nil true true false nil if: true " ! if: true " if: false !
  28. (b = !b)...(fizz_flipflop) b=… flip-flop State nil true nil if:

    true " ! true nil false true nil false if: true " true nil true true false nil if: true " ! false true nil if: true " if: false ! if: true " !
  29. a=b=c = nil # Initialisierung! ! (1..100).each do |num| fizz

    = true unless (a = !a) .. (a = !a) buzz = true unless (b = !b) ... !((c = !c) .. (c = !c)) ! print_it(num, fizz, buzz) end ✔
  30. a=b=c = nil # Initialisierung! ! (1..100).each do |num| fizz

    = true unless (a = !a) .. (a = !a) buzz = true unless (b = !b) ... !((c = !c) .. (c = !c)) ! print_it(num, fizz, buzz) end ✔ ✔
  31. 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz

    11 Fizz 13 14 FizzBuzz 16 … a=b=c = nil # Initialisierung! ! (1..100).each do |num| fizz = true unless (a = !a) .. (a = !a) buzz = true unless (b = !b) ... !((c = !c) .. (c = !c)) ! print_it(num, fizz, buzz) end
  32. a=b=c=(1..100).each do |num| print num, ?\r, ("Fizz" unless (a =

    !a) .. (a = !a)), ("Buzz" unless (b = !b) ... !((c = !c) .. (c = !c))), ?\n end
  33. ★ Sehr viel Komplexität ★ Extrem unbekannt ★ Schlecht zu

    debuggen ★ Für awk/sed Funktionalität „sinnvoll“ d Finger weg!!!
  34. Harassment, Misogyny and Hatred against women and minorities in IT

    and Open Source Harassment, Misogyny and Hatred against women and minorities in IT and Open Source
  35. Thanks! Dirk Breuer / @railsbros_dirk Sebastian Cohnen / @tisba http://geekstammtisch.de

    QaA “My Little Pony” © Hasbro Studios and DHX Media Vancouver ✗