Conversation
|
I like it. If you want to make the names shorter, maybe |
|
The words "prefix" and "suffix" are more concise and descriptive than "starts-with" and "ends-with". "Enclosed-by" seems awkward; "wrapped-in" feels more natural to me, and is probably more accessible to non-native English speakers. |
|
Thanks. Indeed, I hesitated with I see your update: |
|
Why would the ensure- functions not have the full string at the end? |
sorry, I badly expressed myself: the existing functions with "prefix" have a different signature: (defun prefix (items)
(defun common-prefix (items)
(defun prefix? (items prefix) ;; <-- not S, as a full word so using "start-with…" would feel more consistent. |
|
Disregard, I was confused, all is well. |
|
Could you clarify a typical use case for these functions? It could help with the naming. In particular just calling it prefix and suffix makes me ask, what happens in this case: Just from the name, should that give us "/bar" or "/babar"? The code clearly suggests it's the latter, but without knowing the use case the function name (and even documentation) feels a little ambiguous. Many of your test-cases seem to suggest single character prefixes, maybe that's where the use case lies? Another naming direction you could with is something like concat-if-required (not that exactly, but something of that manner) |
|
What's the difference with |
|
The ensure- functions return a string that has the specified prefix or suffix, appened if necessary. |
|
My typical use-case if for slashes with URIs: (str:ensure-starts-with "/" "foo/bar") ;; => /foo/bar/ (edited for middle / )
(str:ensure-enclosed-by "/" "9278-uuid-123") ;; => "/9278-uuid-123/"in that case, that's a poor man URI handling when I don't want (or need) to reach for a proper lib like Quri. (str:ensure-starts-with "bar" "/ba")
"bar/ba" |
|
@vindarel Oh sorry I meant (str:ensure-starts-with "/ba" "bar"). The shortest way to "ensure" that "bar" starts with "/ba" is to just prepend a "/" |
|
I agree with your use case btw, I can see myself using that frequently. Just not sure about the semantics or usefulness of multi-character prefixes/suffixes. |
|
I was trying to figure out real world situations where multi-character prefixs and suffixes come up, this is the best I got:
|
|
yeah, good catch for the multi-character prefixes/suffixes. I didn't have such a use-case, so gotta give them more thought. For this use-case though: You might be on to something with this use case: (str:ensure-starts-with "https://" "www.example.com") ;; = logical
(str:ensure-starts-with "https://" "https://www.example.com") ;; = nothing to do here
;; but here:
(str:ensure-starts-with "https:// "http://www.example.com") ;; => should it give "https://www.example.com" ?if it should be the default behavior, another function or a keyword argument, I'll see. But I didn't meet the use case, our examples are URI-specific, so I'll probably stay simple with the current behavior. |
This one should definitely not be part of cl-str. My URI examples were mostly for "first-pass", "hacky" implementations. It's convenient to just to string handling when you're just prototyping something. PS. I went through my code base trying to find where this pattern shows up, the trailing slash shows up in several locations. The exact pattern of checking if it's a suffix and only then appending happens only at one place: https://github.com/screenshotbot/screenshotbot-oss/blob/main/src/util/store.lisp#L46 (copied from my internal repo), but there are several other places where I just do |
|
I renamed the functions to I noticed a difference in a hedge case: (str:starts-with-p nil "rst")
NIL
CL-USER> (str:wrapped-in-p nil "rst")
"rst"I didn't add something for CL-USER > (url-parse "google.com" :path "/index.html")
http://google.com/index.html
;; and then:
CL-USER > (url-parse * :scheme "https")
https://google.com/?s=common+lisphttps://github.com/massung/url (not on QL) With Quri… ok, not so bad. CL-USER> (quri:merge-uris (quri:uri "/index.html") (quri:uri "https://en.wikipedia.org/wiki/URL"))
#<QURI.URI.HTTP:URI-HTTPS https://en.wikipedia.org/index.html>
CL-USER> (format nil "~a" *)
"https://en.wikipedia.org/index.html"There's also a commit that says "Let merge-uris accept string parameters." "As it did in version 0.4.0." and this was many months ago, looks like I'm lagging behind) |
|
The idea of ensure function is nice. One more option could be having one function with
Or with different parameter-names
|
|
Good idea. Something like (defun ensure (s &key start end wrapped-in)
(cond
(wrapped-in
(ensure-wrapped-in wrapped-in s))
((and start end)
(ensure-start start (ensure-end end s)))
(start
(ensure-start start s))
(end
(ensure-end end s)))
(t
s)))in that case, a ":start" key is weird and too different than its usual meaning, so probably ":prefix" is better. This leads again to my hesitation to use |
|
re. naming, I now tend to |
|
Yes, prefix/suffix makes more sense, even if you look up dictionary: prefix / suffix. Here I have an exemplary implementation of partial prefix adding (defun ensure-prefix (prefix s)
(labels ((add-prefix (remaining-prefix)
(cond ((emptyp remaining-prefix)
(concat prefix s))
((starts-with-p remaining-prefix s)
(concat (subseq prefix 0 (1+ (length remaining-prefix)))
s))
(t
(add-prefix (s-rest remaining-prefix))))))
(if (or (null prefix)
(starts-with-p prefix s))
s
(add-prefix (s-rest prefix)))))
(ensure-prefix "abc" "c3235") ;=> "abc3235"We could implement |
|
Alright, thanks, let's name them properly and merge quick, I have code using these functions now!
but this is too weird, I need a strong rationale to add this, but definitely not in the "ensure" functions nor in this PR. I questioned the possibility, but it was discarded by the discussion. For URLs, there are URL handling libraries. |
Example:
Feedback welcome (especially for naming).