-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
String#tr: don't crash if replacement is empty #3129
Conversation
Raise ArgumentError instead. It used to crash with IndexError. This should fix #3121.
Wouldn't it be better to call delete so it would match Ruby behaviour? $ ruby -e "puts '12'.tr('1','')"
It makes it better to use than having to deal with the exception. I'm thinking sometimes the parameter might come from user input or having it raise seems less dev friendly. On Tue, Aug 9, 2016 at 9:57 PM, Patrik Wenger notifications@github.com
|
You're right. Didn't think that far. 😅 I'll improve it. |
What about now? :) |
I'm not sure I agree, I never used |
I've seen a couple of times Ruby code like It's safe to assume then that you expect it to work for any value of var, On Tue, Aug 9, 2016 at 10:18 PM, Jonne Haß notifications@github.com wrote:
|
https://github.com/search?q=gsub&ref=simplesearch&type=Code&utf8=%E2%9C%93 Searching for .tr is too hard on github since search doesn't support . chars On Tue, Aug 9, 2016 at 10:36 PM, Luis Landeiro Ribeiro <
|
Uhm, |
It boils down to:
I don't really have a strong opinion. The Ruby world deals with (1). Granted, (2) does seem cleaner/safer. |
I'm also hesitant about either route, but using some examples: "hello".tr("el", "ay") # replace 'e' with 'a' and 'l' with 'y'
"hello".tr("el", "a") # replace 'e' and 'l' with 'a'
"hello".tr("el", "") # replace 'e' and 'l' with nothing, so delete them I think it doesn't hurt if we simply delegate to Side note: Ruby's |
Like I said, I don't have a strong opinion. I also don't have a lot of experience with Crystal yet, so no intuition on how this ought to be solved. Character ranges and negating sets are indeed missing and could be a nice Crystal programming exercise. It'd most likely be more performant/have a smaller footprint than using |
Just a side note here: damn how nice it would be if things like this could error at compile time when literals are used (can via macro wrapping). Well, anyways... Out of a psychological perspective, perhaps defining result for any input would make a user more aware of covering odd cases. And dub these as "bad form" in the docs (ie: "worse style than using Like:
In an utopian world it should of course be very simple. |
I like @ozra's suggestion about erroring at compile-time if class Str
getter string
def initialize(@string : String)
end
def tr(from : String, to : String)
{% if to.is_a?(StringLiteral) && to.empty? %}
{{raise}}
{% else %}
@string.tr(from, to)
{% end %}
end
end
s = Str.new "Foo"
p s.tr("o", "i")
p s.tr("o", "") Unfortunately I don't have access to |
i think that's the best of both worlds if we can pull it off. If not, i like the defaulting to calling delete if it's empty. |
Really, I think making tr a macro just for this is completely over-engineering the solution to this problem. If people want to use tr with an empty string instead of delete let them, it's their own code. |
@paddor Thank you! I merged because of #3129 (comment) and because I agree with @RX14, we are over-discussing this. As a side note, you can't currently have macros on class instances, only on classes. |
No description provided.