From: ara.t.howard@... Date: 2006-12-07T01:02:10+09:00 Subject: Re: invasive parameters as method mode variables On Thu, 7 Dec 2006, Trans wrote: > Working on a method where I would like one part of it's operations to > be optional. Here's the crux of the code: > > def parse_multicommand( line=nil, arity={} ) > argv = parse_line(line) > argv = multi_flag(argv) # optional? > > # ... > end > > I would prefer not to add another parameter to the method signiture to > signify this option b/c its rare and it would complexify the call to > much, especially if there is more than one optional part --which is > possible. But other tahn that I don't have much choice, I'll probably > have to create an extra method called > #parse_multicommand_without_multi_flag. Yuk! > > Not that helps me presently, but this did get me to thinking of using a > "global" flag that can be set external to the method. That would work > but it wouldn't be thread safe. Then it occured to me the > Binding.of_caller could be helpful here. Using the Binding#[] extension > for local variable access: > > def parse_multicommand( line=nil, arity={} ) > argv = parse_line(line) > argv = multi_flag(argv) unless Binding.of_caller[:no_multi_flag] > > # ... > end > > Then to use: > > no_multi_flag = true > parse_multicommand( line ) > > I know this breaks the whole idea of function encapsulation, but it has > it's advantages in certain cases like mine. It also might be of usedin > a few other places like String#each's separator. So that got me to > thinking of a cleaner way to provided this capability of invasive > parameters as "method mode variables". > > def parse_multicommand( line=nil, arity={} ) > argv = parse_line(line) > argv = multi_flag(argv) unless --no_multi_flag > > # ... > end > > # '--' indicates a method mode variable > --no_multi_mode = true > parse_multicommand( line ) > > Thouhgts? method + state => object harp:~ > cat a.rb require 'rubygems' require 'attributes' class Parser attribute 'no_multi_flag' def parse_multicommand p [:parse_multicommand, no_multi_flag] end def parsing &b instance_eval &b end end parser = Parser.new parser.parsing{ no_multi_flag true parse_multicommand } harp:~ > ruby a.rb [:parse_multicommand, true] fun to clean up with prototype: harp:~ > cat a.rb require 'rubygems' require 'prototype' parser = prototype{ no_multi_flag false def parse_multicommand p [:parse_multicommand, no_multi_flag] end def parsing &b instance_eval &b end } parser.parsing{ parse_multicommand } parser.parsing{ no_multi_flag true parse_multicommand } harp:~ > ruby a.rb [:parse_multicommand, false] [:parse_multicommand, true] regards. -a -- if you want others to be happy, practice compassion. if you want to be happy, practice compassion. -- the dalai lama