Professional Web Applications Themes

flip flop operator and assignment - Ruby

I'm working on the pattern matching section for http://pleac.sourceforge.net/pleac_ruby/t1.html (an attempt to duplicate the Perl Cookbook for several languages including Ruby). The Perl code that needs to be duplicated in Ruby is: while (<>) { $in_header = 1 .. /^$/; $in_body = /^$/ .. eof(); } In Ruby first I tried: File.open("filename"){|f| f.each_line {|l| in_header = $.==1 .. l=~/^$/ in_body = l=~/^$/ .. f.eof puts "in_header: #{l}" if in_header puts "in_body: #{l}" if in_body } } But that give the following error: ArgumentError: bad value for range However, when I changed it to use the ternary operator, like so: File.open("filename"){|f| ...

  1. #1

    Default flip flop operator and assignment

    I'm working on the pattern matching section for
    http://pleac.sourceforge.net/pleac_ruby/t1.html (an attempt to duplicate
    the Perl Cookbook for several languages including Ruby).

    The Perl code that needs to be duplicated in Ruby is:
    while (<>) {
    $in_header = 1 .. /^$/;
    $in_body = /^$/ .. eof();
    }


    In Ruby first I tried:

    File.open("filename"){|f|
    f.each_line {|l|
    in_header = $.==1 .. l=~/^$/
    in_body = l=~/^$/ .. f.eof
    puts "in_header: #{l}" if in_header
    puts "in_body: #{l}" if in_body
    }
    }

    But that give the following error:
    ArgumentError: bad value for range

    However, when I changed it to use the ternary operator, like so:

    File.open("filename"){|f|
    f.each_line {|l|
    in_header = $.==1 .. l=~/^$/ ? true : false
    in_body = l=~/^$/ .. f.eof ? true : false
    puts "in_header: #{l}" if in_header
    puts "in_body: #{l}" if in_body
    }
    }

    It then works.

    What gives? It seems that the flip/flop operator is evaluating to true or
    false, why can't I just assign that value to in_header or in_body?

    Phil
    Phil Guest

  2. #2

    Default Re: flip flop operator and assignment

    >>>>> "P" == Phil Tomson <com> writes:

    P> in_header = $.==1 .. l=~/^$/

    this is not the flip flop operator, but the range operator : this is why
    it give an error

    P> in_header = $.==1 .. l=~/^$/ ? true : false

    this is the flip flop operator


    Guy Decoux




    ts Guest

  3. #3

    Default Re: flip flop operator and assignment

    In article <inra.fr>,
    ts <inra.fr> wrote: [/ref]
    >
    >P> in_header = $.==1 .. l=~/^$/
    >
    > this is not the flip flop operator, but the range operator : this is why
    > it give an error
    >
    >P> in_header = $.==1 .. l=~/^$/ ? true : false
    >
    > this is the flip flop operator[/ref]

    Yes, I figured that it was being interpreted that way, but my question is
    why?

    this part:
    $.==1 .. l=~/^$/

    is the same in both statements. Why does it get interpreted as a range in
    one case, and a flip flop in the other?

    I could see that if I did: ($.==1 .. l=~/^$/) that the interpreter could
    get the idea that it's a range, but it would be a range like this:
    (false..true) or (true..false) because $.==1 has to evaluate to either
    true or false. If I try either one of these in irb I get:

    (true..false)
    ArgumentError: bad value for range

    (false..true)
    ArgumentError: bad value for range

    so it appears that you can't have a range of TrueClass, FalseClass
    therefore why doesn't the interpreter think it's a flip/flop operator?

    Phil
    Phil Guest

  4. #4

    Default Re: flip flop operator and assignment

    >>>>> "P" == Phil Tomson <com> writes:

    P> Yes, I figured that it was being interpreted that way, but my question is
    P> why?

    ruby use `..' for the range operator and the flip-flop operator.

    When it see `..' in a condition, it transform the range operator into the
    flip-flop operator.

    a .. b # range operator
    a .. b?true:false # flip-flop operator
    if a .. b; end # flip-flop operator


    Guy Decoux


    ts Guest

  5. #5

    Default Re: flip flop operator and assignment

    ts wrote:
     [/ref]
    >
    >P> Yes, I figured that it was being interpreted that way, but my question is
    >P> why?
    >
    > ruby use `..' for the range operator and the flip-flop operator.
    >
    >[/ref]

    Reading the posts in this discussion has been very enlightening for me.
    I finally understand the flip-flop operator, for one thing. And I think
    I understand the root of the "dislike" some people have for the
    flip-flop: it uses the same syntax as a completely unrelated (and
    possibly more common) concept, which can make the intuitive leap a bit hard.

    I can certainly see the value in the flip-flop, and where I was
    originally on the "team" that was rooting for its removal, I now would
    like to see it remain, but in different form. What if it used a
    different syntax, but the same semantics? This would allow the
    flip-flop to be used outside of conditionals, too, since there would be
    no ambiguity involved.

    So, instead of '..' and '...', how about something completely new, like
    perhaps '--', or '~~'? Or even a new keyword, like 'flip' or
    'flipflop'? It would be nice to also somehow provide a way to access
    some underlying objectified represention of the flip-flop, so that its
    state could be queried and manipulated,

    My $0.02.

    - Jamis

    --
    Jamis Buck
    byu.edu

    ruby -h | ruby -e 'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/) {|r| a << r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'



    Jamis Guest

  6. #6

    Default Re: flip flop operator and assignment

    Hi,

    At Tue, 3 Feb 2004 13:08:50 +0900,
    Jamis Buck wrote: 

    Ruby already has both of unary and binary '-' operators, so the
    former will conflict. But '~' operator is only unary now, the
    later wouldn't.

    --
    Nobu Nakada


    nobu.nokada@softhome.net Guest

  7. #7

    Default Re: flip flop operator and assignment

    net wrote:
     
    >
    >Ruby already has both of unary and binary '-' operators, so the
    >former will conflict. But '~' operator is only unary now, the
    >later wouldn't.
    >
    >
    >[/ref]
    Good point. Another option would be to retain the use of the '..' and
    '...', but prefix any flip-flop expression with some disambiguating
    operator or keyword, a la:

    a .. b #-> range
    flip a..b # -> flip-flop

    With that, you could then add another piece of syntax to obtain the
    internal "objectified" representation:

    flip a..b => c

    The expression would still return boolean, as the regular flip-flop, but
    would assign the object to 'c', which could then be manipulated and queried:

    current_value = c.get_state
    c.set_state( false )

    - Jamis

    --
    Jamis Buck
    byu.edu

    ruby -h | ruby -e 'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/) {|r| a << r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'



    Jamis Guest

  8. #8

    Default Re: flip flop operator proposal (from condition to condition do )

    Jamis Buck <byu.edu> wrote in message news:<byu.edu>... 
    > >
    > >P> Yes, I figured that it was being interpreted that way, but my question is
    > >P> why?
    > >
    > > ruby use `..' for the range operator and the flip-flop operator.
    > >
    > >[/ref]
    >
    > Reading the posts in this discussion has been very enlightening for me.
    > I finally understand the flip-flop operator, for one thing. And I think
    > I understand the root of the "dislike" some people have for the
    > flip-flop: it uses the same syntax as a completely unrelated (and
    > possibly more common) concept, which can make the intuitive leap a bit hard.
    >
    > I can certainly see the value in the flip-flop, and where I was
    > originally on the "team" that was rooting for its removal, I now would
    > like to see it remain, but in different form. What if it used a
    > different syntax, but the same semantics? This would allow the
    > flip-flop to be used outside of conditionals, too, since there would be
    > no ambiguity involved.
    >
    > So, instead of '..' and '...', how about something completely new, like
    > perhaps '--', or '~~'? Or even a new keyword, like 'flip' or
    > 'flipflop'? It would be nice to also somehow provide a way to access
    > some underlying objectified represention of the flip-flop, so that its
    > state could be queried and manipulated,[/ref]

    -- would look too much like decrement (from the perspective of other
    languages) so that could also be confusing. ~~ might be better.

    'flipflop' is the object, not the action and in this case it seems
    like you're basically trying to say:

    "do something from the time condition A becomes true until the time
    condition B becomes true". Perhaps, as you say, a new keyword is in
    order. But what if we could make use of an existing keyword; I'm
    thinking that 'until' might work. It would look something like:

    if l=~/BEGIN/ until l=~/END/ do
    #do something in this range
    end

    Actually, I don't think 'until' is really a keyword (correct me if I'm
    wrong), but that it's actually a buit-in method that takes a block, so
    it might be difficult to coerce it into this proposed usage.

    Another idea would be to have a 'from (condition) to (condition)'
    statement that looks looks like:
    from l=~/BEGIN/ to l=~/END/ do
    #do something in this range
    end

    Then we just need some way to determine if the range is inclusive or
    exclusive...
    from l=~/BEGIN/ to l=~/END/ inclusive do
    puts l
    end

    #prints:
    BEGIN
    foo
    bar
    END

    from l=~/BEGIN/ to l=~/END/ exclusive do
    puts l
    end

    #prints:
    foo
    bar

    ....but maybe there's a better way to do that. Also, how do you get
    the same kind of behavioral differences that we see with the current
    ... and ... flip flop operators?

    It seems like the 'from (condition) to (condition)' statement could
    also return the underlying flip/flop object, kind of like [] returns
    an Array or {} returns a Hash. So there could still be a FlipFlop
    class, but this would just be a shortcut that keeps you from having to
    instantiate a FlipFlop object explicitly prior to use.

    ff = from l=~/BEGIN/ to l=~/END/ { ... }
    OR:
    from l=~/BEGIN/ to l=~/END/ {|ff| ... }

    then you could call methods on the ff object, like:
    ff.status? (true or false)
    ff.class #=> FlipFlop

    I'm just sort of brainstorming here, but I think the 'from .. to ..
    {}' statement is very readable and the intent is quite clear and it
    just might be able to replace the current flipflop operators.

    Phil
    Phil Guest

  9. #9

    Default Re: flip flop operator proposal (from condition to condition do )

    Phil Tomson wrote: 
    >>
    >>Reading the posts in this discussion has been very enlightening for me.
    >>I finally understand the flip-flop operator, for one thing. And I think
    >>I understand the root of the "dislike" some people have for the
    >>flip-flop: it uses the same syntax as a completely unrelated (and
    >>possibly more common) concept, which can make the intuitive leap a bit hard.
    >>
    >>I can certainly see the value in the flip-flop, and where I was
    >>originally on the "team" that was rooting for its removal, I now would
    >>like to see it remain, but in different form. What if it used a
    >>different syntax, but the same semantics? This would allow the
    >>flip-flop to be used outside of conditionals, too, since there would be
    >>no ambiguity involved.
    >>
    >>So, instead of '..' and '...', how about something completely new, like
    >>perhaps '--', or '~~'? Or even a new keyword, like 'flip' or
    >>'flipflop'? It would be nice to also somehow provide a way to access
    >>some underlying objectified represention of the flip-flop, so that its
    >>state could be queried and manipulated,[/ref]
    >
    >
    > -- would look too much like decrement (from the perspective of other
    > languages) so that could also be confusing. ~~ might be better.
    >
    > 'flipflop' is the object, not the action and in this case it seems
    > like you're basically trying to say:
    >
    > "do something from the time condition A becomes true until the time
    > condition B becomes true". Perhaps, as you say, a new keyword is in
    > order. But what if we could make use of an existing keyword; I'm
    > thinking that 'until' might work. It would look something like:
    >
    > if l=~/BEGIN/ until l=~/END/ do
    > #do something in this range
    > end
    >
    > Actually, I don't think 'until' is really a keyword (correct me if I'm
    > wrong), but that it's actually a buit-in method that takes a block, so
    > it might be difficult to coerce it into this proposed usage.[/ref]

    It's a kewyword:

    irb(main):001:0> until(1) {}
    irb(main):002:1> end
    SyntaxError: compile error
    (irb):1: p error
    until(1) {}
    ^
    from (irb):2
     

    Very readable! It may be an improvement that the flipflop isn't being
    used with if, but with a special keyword. The hidden state bothers me
    less that way. Of course you lose the possibility of a condition with
    more complex logic.



    Joel Guest

  10. #10

    Default Re: flip flop operator proposal (from condition to condition do )

    Joel VanderWerf <Berkeley.EDU> wrote in message news:<berkeley.edu>... [/ref]
     
    >
    > Very readable! It may be an improvement that the flipflop isn't being
    > used with if, but with a special keyword. The hidden state bothers me
    > less that way. Of course you lose the possibility of a condition with
    > more complex logic.[/ref]

    Couldn't you just use the returned FlipFlop object for those purposes?

    ff = from l=~/BEGIN/ to l=~/END/ #no block passed in

    then you could do things with ff:
    if ff.set?
    #do something
    else
    #do something else
    end

    The from (condition) to (condition) would just be syntactic sugar for
    the creation of a FlipFlop object. (kind of like [] is for Array and
    {} is for Hash, or lamda is for Proc). Come to think of it, couldn't
    ff be a functional object, kind of like a closure (Proc)? Actually,
    it's probably more like a set of conditions that a Proc must evaluate
    when it (the block being passed in to the from .. to .. ) is called.

    ....just thinking out loud. Should probably try to prototype something
    that doesn't require any syntax changes.

    Phil
    Phil Guest

  11. #11

    Default Re: flip flop operator proposal (from condition to condition do )

    Phil Tomson wrote:
     

    What if we just use the keyword 'in' to introduce a flipflop, and retain
    the range-ish syntax to separate the conditions? Something like this:

    if in l=~/BEGIN/ .. l=~/END/
    ...
    end

    The advantage of using a boolean phrase is that you can use it in
    conditions, where it is most common. That also lets you do something
    when the flipflop is false, which the 'from..do' construct you suggested
    doesn't (easily) allow.

    Since getting at the object that encapsulates the state of the flipflop
    will be less common (one might even say "rare", although its hard to say
    at this point since neither Perl nor Ruby allow it), the common case
    (just getting the boolean result) should be simple and straightforward.
    Getting at the object might be done via something like this:

    in l=~/BEGIN/ .. l=~/END/ => state

    The expression itself still returns boolean, but the object
    encapsulating the flipflop is placed in 'state'.

    I took the 1.8.1 source and tried hacking at it to introduce this
    syntax, and managed to get the 'in' keyword working as above. Problem
    is, I'm not a bison expert, and I'm certainly not very familiar with the
    inner workings of Ruby's pr, so I keep getting 2 reduce/reduce
    conflicts caused by the 'in' keyword... not sure how to fix that. And
    when I try to use '=>' to assign the object, I get 27 shift/reduce
    conflicts (which I think I understand, but I'm not sure how to fix).
    I'd be happy to send a patch to anyone interested, but it's really
    pretty trivial, and (as I said) imperfect.

    I tried introducing new keywords to fill these roles, but the means by
    which Ruby does its keyword lookup is pretty arcane, and it is not
    immediately obvious how to add a new keyword. Any gurus of Ruby's inner
    workings that could clarify how to do this?

    I'd be especially interested in hearing from the proponents of the
    flip-flop operator in Ruby as to whether this suggestion would "fit the
    bill." If it isn't something they'd be comfortable using, then it is
    probably not the most appropriate solution to the problem. However, I
    think it gets the best of both worlds -- it is clearer that you're
    dealing with more than just a range, and you can use it in more places
    than simply in conditions.
     

    I agree, 'from .. to ...' is very readable, but perhaps not as
    convenient given the regular usage of the flip-flop operator. Then
    again, I'd like to hear from someone who uses the flip-flop a lot as to
    whether they feel it would be bersome. Readability is good, but if
    you take it too far you get VB and Pascal, which are easy to learn, but
    clunky (IMO) to actually write software in.

    --
    Jamis Buck
    byu.edu

    ruby -h | ruby -e 'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/) {|r| a << r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'



    Jamis Guest

  12. #12

    Default Re: flip flop operator proposal (from condition to condition do )

    Hi,

    At Wed, 4 Feb 2004 09:21:49 +0900,
    Jamis Buck wrote: 

    Agreed, and it seems easy to implement.
     

    How will you use it, in other words, how and when it will be
    changed?


    Index: node.h
    ================================================== =================
    RCS file: /cvs/ruby/src/ruby/node.h,v
    retrieving revision 1.52
    diff -u -2 -p -d -r1.52 node.h
    --- node.h 22 Jan 2004 08:31:33 -0000 1.52
    +++ node.h 4 Feb 2004 00:53:13 -0000
    -327,4 +327,6 typedef struct RNode {
    #define NEW_DOT2(b,e) NEW_NODE(NODE_DOT2,b,e,0)
    #define NEW_DOT3(b,e) NEW_NODE(NODE_DOT3,b,e,0)
    +#define NEW_FLIP2(b,e) NEW_NODE(NODE_FLIP2,b,e,local_append(internal_id() ))
    +#define NEW_FLIP3(b,e) NEW_NODE(NODE_FLIP3,b,e,local_append(internal_id() ))
    #define NEW_ATTRSET(a) NEW_NODE(NODE_ATTRSET,a,0,0)
    #define NEW_SELF() NEW_NODE(NODE_SELF,0,0,0)
    Index: p.y
    ================================================== =================
    RCS file: /cvs/ruby/src/ruby/p.y,v
    retrieving revision 1.315
    diff -u -2 -p -d -r1.315 p.y
    --- p.y 3 Feb 2004 02:23:20 -0000 1.315
    +++ p.y 4 Feb 2004 00:53:13 -0000
    -619,4 +619,12 expr : command_call
    $$ = NEW_NOT(cond($2));
    }
    + | kIN arg tDOT2 arg
    + {
    + $$ = NEW_FLIP2($2, $4);
    + }
    + | kIN arg tDOT3 arg
    + {
    + $$ = NEW_FLIP3($2, $4);
    + }
    | arg
    ;


    --
    Nobu Nakada


    nobu.nokada@softhome.net Guest

  13. #13

    Default Re: flip flop operator proposal (from condition to condition do )

    In article <byu.edu>,
    Jamis Buck <byu.edu> wrote: 
    >
    >What if we just use the keyword 'in' to introduce a flipflop, and retain
    >the range-ish syntax to separate the conditions? Something like this:
    >
    > if in l=~/BEGIN/ .. l=~/END/
    > ...
    > end
    >
    >The advantage of using a boolean phrase is that you can use it in
    >conditions, where it is most common. That also lets you do something
    >when the flipflop is false, which the 'from..do' construct you suggested
    >doesn't (easily) allow.
    >
    >Since getting at the object that encapsulates the state of the flipflop
    >will be less common (one might even say "rare", although its hard to say
    >at this point since neither Perl nor Ruby allow it), the common case
    >(just getting the boolean result) should be simple and straightforward.
    >Getting at the object might be done via something like this:
    >
    > in l=~/BEGIN/ .. l=~/END/ => state[/ref]
    <snip> 
    >
    >I agree, 'from .. to ...' is very readable, but perhaps not as
    >convenient given the regular usage of the flip-flop operator. Then
    >again, I'd like to hear from someone who uses the flip-flop a lot as to
    >whether they feel it would be bersome. Readability is good, but if
    >you take it too far you get VB and Pascal, which are easy to learn, but
    >clunky (IMO) to actually write software in.[/ref]

    I use the flip-flop pretty commonly when I'm parsing files. For my usage,
    the from..to.. would probably work fine:

    #not a real example, of course
    File.foreach{|l|
    from l=~/BEGIN/ to /END/ do
    #nesting should work ok
    from l=~/def/ to /end/ do
    #method definition
    end
    from l=~/from/ to /end/ do
    #proposed syntax, p thyself
    end
    end
    #would we need elsfrom?
    from l=~/<html>/i to l=~/</\html>/i
    #in an HTML file
    end
    }

    But others have suggested that they use the flipflop for other things. I
    think that if the from construct returns a FlipFLop object that it would
    be useable for these other appliations as well, but I'd like to hear some
    other suggestions.

    Maybe the from..to.. construct should just return a boolean, then it would
    be used with an if statement like:

    if from (condition) to (condition)

    But using 'from' could still be slanted more toward the file parsing
    application, rather than a more general purpose usage. I thought of
    'from' because that's the main way I use the flip/flop operator.

    BTW: I really don't like the 'flip' idea:

    if flip (condition) to (condition)

    because it's not clear from reading it what 'flip' means.

    Phil
    Phil Guest

  14. #14

    Default Re: flip flop operator proposal (from condition to condition do )

    net wrote:
     
    >
    >Agreed, and it seems easy to implement.
    >
    >[/ref]

    As evidenced by your patch. Thanks!
     
    >
    >How will you use it, in other words, how and when it will be
    >changed?
    >
    >
    >[/ref]

    I suggested this primarily because there were a few posters that
    mentioned the fact that the "hidden state" aspect of the flip-flop op
    turned them off from the whole concept. By exposing the state, it makes
    it less "mysterious". However, I'll give a very contrived example of
    where it might be useful. Suppose you had an input file that contained
    the following:

    BEGIN
    1
    2
    special
    3
    END

    In general, you want a pr that extracts everything between BEGIN and
    END, but there are a few cases where you want to treat the word
    'special' as the end instead, and then ignore everything until the next
    BEGIN.

    while line = file.gets
    if in line=~/BEGIN/ .. line=~/END/ => state
    state.set_state( line =~ /special/ )
    if state.get_state
    # process line
    end
    end
    end

    Like I said, it's pretty contrived, and would be better solved by
    choosing smarter guard conditions. However, it demonstrates a situation
    where exposing an interface for manipulating a flip-flop's state may be
    useful.

    --
    Jamis Buck
    byu.edu

    ruby -h | ruby -e 'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/) {|r| a << r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'



    Jamis Guest

  15. Moderated Post

    Default Re: flip flop operator proposal (from condition to condition do )

    Removed by Administrator
    nobu.nokada@softhome.net Guest
    Moderated Post

  16. #16

    Default Re: flip flop operator proposal (from condition to condition do )

    net wrote:
     
    >
    >Will set_state turn the state true, or false? Seeing the next
    >line, set_state(true) makes get_state to return false...
    >
    >
    >[/ref]

    Well, what I had envisioned was the following:

    FlipFlip#get_state: return the current truth value of the flip flop.
    FlipFlop#set_state( state ): set the truth value of the flip flop

    And you're right -- there's a typo in my example. :( The set_state call
    should be:

    state.set_state( line !~ /special/ )
     
    >
    >Rather, what about binding a flip-flop operator to a local
    >variable?
    >
    >[/ref]

    Fascinating concept--that would certainly be simpler. The only benefit
    I can see to using an object as opposed to a local variable binding is
    that you could pass the flipflop object into a method and have any
    manipulations made on it in the method be effective outside the method.

    --
    Jamis Buck
    byu.edu

    ruby -h | ruby -e 'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/) {|r| a << r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'



    Jamis Guest

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139