Prev: Module boundaries and classes within them (Was: Re: Placement ofrequire() and missing symbols)
Next: unicorn 1.0.0 - yes, this is a real project
From: Intransition on 17 Jun 2010 10:24 I've never run into this issue before, but I'm working on a method interface that is quite 'dense', and I need to be able to differentiate between a hash passed to a method and named parameters. i.e. All of these are valid: foo(hash, :opt=>val) foo(hash) foo(:opt=>val) However, there seems to be no way to distinguish that last the two forms. Is there any way? Or am I stuck?
From: Josh Cheek on 17 Jun 2010 11:25 [Note: parts of this message were removed to make it a legal post.] On Thu, Jun 17, 2010 at 9:24 AM, Intransition <transfire(a)gmail.com> wrote: > I've never run into this issue before, but I'm working on a method > interface that is quite 'dense', and I need to be able to > differentiate between a hash passed to a method and named parameters. > i.e. All of these are valid: > > foo(hash, :opt=>val) > foo(hash) > foo(:opt=>val) > > However, there seems to be no way to distinguish that last the two > forms. > > Is there any way? Or am I stuck? > > I would expect stuck, because the difference seems nothing more than visual. (ie if the options hash was assigned to a var, rather than created within the arg list, then the last two would be exactly the same) though it does seem unusual that there is not a method like options_given? the way there is a block_given? I suppose if this method interface is absolutely necessary, then a hack you might be able to get away with would be to check the keys to see if they match up with your options. But I would be embarrassed to show anyone such a solution ;) Something to consider, though, whatever param the hash is an arg for, is optional (ie omitted in your third invocation). So perhaps it would fit better into the options hash, which you could then extract it from, inside the method: def foo( options = Hash.new ) the_hash = options.delete(:the_hash) { Hash.new } [ the_hash , options ] end hash = Hash[*1..4] val = :val foo( :the_hash => hash , :opt => val ) # => [{1=>2, 3=>4}, {:opt=>:val}] foo( :the_hash => hash ) # => [{1=>2, 3=>4}, {}] foo( :opt => val ) # => [{}, {:opt=>:val}]
From: Roger Pack on 17 Jun 2010 16:15 > foo(hash) > foo(:opt=>val) > > However, there seems to be no way to distinguish that last the two > forms. One possibility would be to check for known keys in the hash. If they're there, assume it's an options hash. Another might be to allow them to input it like :hash => hash if they ever want it that way. But you're probably just stuck. -r ref: http://github.com/rdp/arguments -- Posted via http://www.ruby-forum.com/.
From: Intransition on 17 Jun 2010 19:21 On Jun 17, 11:25 am, Josh Cheek <josh.ch...(a)gmail.com> wrote: > > Is there any way? Or am I stuck? > > I would expect stuck, because the difference seems nothing more than visual. > (ie if the options hash was assigned to a var, rather than created within > the arg list, then the last two would be exactly the same) though it does > seem unusual that there is not a method like options_given? the way there is > a block_given? > > I suppose if this method interface is absolutely necessary, then a hack you > might be able to get away with would be to check the keys to see if they > match up with your options. But I would be embarrassed to show anyone such a > solution ;) > > Something to consider, though, whatever param the hash is an arg for, is > optional (ie omitted in your third invocation). So perhaps it would fit > better into the options hash, which you could then extract it from, inside > the method: > > def foo( options = Hash.new ) > the_hash = options.delete(:the_hash) { Hash.new } > [ the_hash , options ] > end > > hash = Hash[*1..4] > val = :val > > foo( :the_hash => hash , :opt => val ) # => [{1=>2, 3=>4}, {:opt=>:val}] > foo( :the_hash => hash ) # => [{1=>2, 3=>4}, {}] > foo( :opt => val ) # => [{}, {:opt=>:val}] Yep. That's what I thought. Appreciate the suggestion. In my case I've decided I'll just have to do without the options hash. I was hoping Ruby 1.9 at least would have had this licked. Early on there was talk of named parameters as: def foo(hash=nil, **opts) But it never came to pass. Thanks.
From: Rein Henrichs on 17 Jun 2010 23:20
On 2010-06-17 07:24:47 -0700, Intransition said: > I've never run into this issue before, but I'm working on a method > interface that is quite 'dense', and I need to be able to > differentiate between a hash passed to a method and named parameters. > i.e. All of these are valid: > > foo(hash, :opt=>val) > foo(hash) > foo(:opt=>val) > > However, there seems to be no way to distinguish that last the two > forms. > > Is there any way? Or am I stuck? If both the second and third option are valid then there is no way to distinguish between the two hashes. If you could narrow it down to one of them, you would be ok. If the hash is optional but the options aren't, you can use: def foo(hash_or_options, options=nil) hash = options ? hash_or_options : nil options = hash_or_options unless options ... end Alternatively, you can pass the original argument as part of the options hash foo(:hash => hash, ...) I assume you're using a more meaningful variable name than 'hash' in the real code, so this may suffice. I would not recommend mixing the two styles in the same method though (allowing a hash argument OR a :hash option). -- Rein Henrichs http://puppetlabs.com http://reinh.com |