> I'm sorry that this message will be long and somewhat rambling, > but I wanted to try to write up my thoughts on this, even though > my thoughts are not very clear... > > There's a situation that I occassionally run into, which I can work > around easy enough, but it seems that there might be an cleaner > solution than the ones I fall back on. Let's say I want to have > something like: > > ARGV.each { |arg| > case arg > when "-f" > ...do something with the *next* value of |arg|... > end > } > > What I do is set some variable to remember that I'm in the middle > of "-f" processing, and then catch that when the code-block is > executed for the next value. For example: Well, if you don't mind trashing the array you're processing you could use Array.shift to remove the first element and return it... then just re-order your loop to exit once the element returns is nil. -philip > > in_option = nil > ARGV.each { |arg| > if in_option > case in_option > when "-f" > ...do the -f processing of this 'arg' value... > end > in_option = nil > next > end > case arg > when "-f" > in_option = arg > end > } > if in_opt > ...some error message about the missing value for an option... > end > > This can be made to work well, but it's a mess in many ways. Please > note that I'm not asking for everyone's favorite package for processing > ARGV, since this same situation comes up (for me at least) in many > other contexts. I am only using ARGV as an convenient example > because everyone will understand what I'm talking about. Also note > that the same situation can come up with 'each_value', 'each_key', > 'each_pair', or other kinds of 'each'-ish methods. > > What I'd like is some way for the '-f' case to say "give me the next > values for 'each'" (perhaps multiple times in a row). If there is no > next-value, then it would get a 'nil' value. > > And to complicate things a bit more, sometimes the option might want > to *check* the next option, but not necessarily use it up. For instance, > if the "-f" option can take one-or-more names, then it would keep taking > the next value for 'arg' until it sees arg =~ /^-/ > > It seems to me that this situation can come up in enough contexts that > the ruby language could provide a way to do it. I have no good idea of > what wording would make sense for this. But the idea would be > something like: > > ARGV.each { |arg| > case arg > when "-f" > opt_value = next_yield(0) > if opt_value and opt_value =~ /^-/ > skip_next_yield > ...do something with that opt_value... > else > $stderr.printf "Error: Missing value for '-f'\n" > opterr = true > end > end > } > > So, what I'm suggesting is two new keywords for ruby. The first would > know what the value(s) would be for the next call to this code-block, but > it would not change anything. The 'skip_next_yeild' would delete that > next value (or set-of-values for methods like each_pair). I added the > parameter to next_yield so that it could also handle the values of > methods like each_pair, eg: > somehash.each_pair { |key, strval| > ...whatever... > next_key = next_yield(0) > next_strval = next_yield(1) > } > I guess next_yield is really an array more than a keyword which takes > a parameter, but I thought it (next_yield) would be more flexible if it > could support other options with additional parameters. > > It might be that 'skip_next_yield' would also take a parameter, which > would be the value the caller should use for the current execution of > the code-block, for those cases where the caller cares about the > return-value from the code-block. 'each' does not care, but a method > like 'sort' would care about the value. > > I'm sure I'm overlooking some details on how this would have to work, > and I'm sure that 'next_yield' and 'skip_next_yield' are dumb names for > those two new keywords. But I think that some feature like the above > could be useful. > > Or is there already some good way to handle this in ruby? > > -- > Garance Alistair Drosehn = drosihn / gmail.com > Senior Systems Programmer > Rensselaer Polytechnic Institute; Troy, NY; USA >