This project is archived and is in readonly mode.
Clean try syntax
-
Amos King
- Tag changed from active_support, core_ext, rails3 to active_support, core_ext, patch, rails3
here is a patch, and it keeps backwards compatibility.
-
Amos King
- Tag changed from active_support, core_ext, patch, rails3 to active_support, core_ext, documentation, patch, rails3
I also updated the documentation in the same patch.
-
José Valim
- State changed from new to wontfix
- Importance changed from to Low
Thanks for the patch, but the syntax something.try[2] is not obvious (for me). try(:[], 2) is simpler with no extra tricks in the implementation.
-
Amos King
This patch supports both syntaxes.
-
José Valim
Yes, but I don't see a reason to support a more complex syntax to be used rather rarely (in :[] cases).
-
yairgo
+1
Are you really going to disregard this patch because the syntax "is not obvious" for you?
I've worked with 5 or 6 people at my company on a rails project that I'm part time on and I've shown at least 4 of them the try(:[], 4) syntax. They've all pretty much said afterward that they would have never even thought to use 'try' that way.
something.try[2] makes a lot more sense to me than something.try(:[],2), one says here try this on my object the other says here is a method and some params try them on my object.
"Yes, but I don't see a reason to support a more complex syntax which is used rather rarely." Is the patch really introducing a more complex syntax?
try[2] vs try(:[], 2) -
Amos King
Why not support both syntaxes for a little while, and see where the community goes with it. Then we can deprecate one, or maybe decide to keep both?
-
José Valim
- Assigned user set to José Valim
Sorry, when I said "complex", I was referring about the implementation required to support such syntax and difficulty to understand what is going on:
self.try(:[], 2) #=> is a method that sends the given method unless self is nil self.try[2] #=> is a method that returns self if not nil, else a proxy that discards any callA proxy just adds complexity:
object.try(:freeze) #=> return nil if object nil object.try.freeze #=> freezes the proxy and returns the proxy if object nilAnother possible failure is with to_json:
require 'json' #=> Ruby 1.9.2 nil.to_json #=> "null" object.try(:to_json) #=> nil object.try.to_json #=> "#<Try:0x00000101826fe8>"There are several other cases where returning a proxy might have a surprising behavior. Note that this is nothing new, we had this discussion a long time ago because there were solutions like andand which had a similar approach to try+proxy and we voted to be explicit with try, since it has no special cases or caveats.
Edited to add proper formatting to block codes.
-
Amos King
What if the implementation used BasicObject if the implementation is Ruby 1.9? I'm not in a place where I can test that right now.
-
José Valim
We could consider that in the future when we drop support for Ruby 1.8.x, but not right now because the implementation would behave considerably different depending on the Ruby version (something that ActiveSupport tries to minimize).
-
Jeremy Kemper
I agree
maybe_hash_maybe_nil.try(:[], key)is ugly. But the proxy approach is error-prone and less obvious.A third way is to use
instance_eval:list.try { self[2] }orobject.try { to_json }. That's clear, but line-noisey.I think the simplest choice is to use
tryfor simple cases and simply do not use it for the few ugly cases. -
Amos King
irb(main):003:0> require 'json'
=> true irb(main):005:0> Try = Class.new(BasicObject) { def method_missing(*) nil; end }
=> Try irb(main):006:0> Try.new.to_json
=> nilThis was with 1.9, and with 1.8.7 it did the same thing.
I'm not sure how you got the Try object with the to_json call.
