היום למדתי: לא כזה פשוט לבנות נתיב ארוך

21/12/2023

הפונקציה os.path.join של פייתון מחברת שמות של כמה נתיבים לנתיב גדול:

>>> import os
>>> os.path.join("/foo", "bar", "buz")
'/foo/bar/buz'

שפות רבות כוללות פונקציה בשם דומה כדי לחבר כמה URL-ים לנתיב אחד ארוך, אבל ההתנהגות הרבה יותר מבלבלת. בפייתון:

>>> import urllib.parse
>>> urllib.parse.urljoin("http://localhost", "blog", "items")
'http://localhost/blog'

בגלל שהפונקציה urljoin מקבלת רק שני פרמטרים עבור החלקים של הנתיב, והפרמטר השלישי הוא בכלל בוליאני שמדבר על היחס לפרגמנטים כמו הדברים שבאים אחרי סולמית או סימן שאלה. אפילו אם נישאר במסגרת של שני פרמטרים זה עדיין יהיה מבלבל:

>>> urllib.parse.urljoin('http://localhost/blog', 'items')
'http://localhost/items'

בגלל שהמילה blog בשם הנתיב לא מסתיימת ב / אז הוא "מוחלף" במילה items. זה כאילו שהיינו מסתכלים על דף אינטרנט בכתובת הראשונה ומקבלים לינק לכתובת השניה, אז התוצאה היתה החלפה של blog ל items. כשאני מוסיף / ההתנהגות יותר דומה למה שהיה לנו בעבודה עם קבצים:

>>> urllib.parse.urljoin('http://localhost/blog/', 'items')
'http://localhost/blog/items'

גם JavaScript תומכת בחיבור URL-ים רק משני חלקים, אבל שם סדר הפריטים הפוך:

> new URL("items", "http://localhost/blog").toString()
'http://localhost/items'
> new URL("items", "http://localhost/blog/").toString()
'http://localhost/blog/items'

רובי כבר מאפשרת להדביק כמה חלקים שאני רוצה ל URL, אבל גם פה יש לנו את ההתנהגות המוזרה עם הלוכסנים:

3.1.1 :006 > URI.join("http://localhost", "blog/", "items").to_s
 => "http://localhost/blog/items"

3.1.1 :007 > URI.join("http://localhost", "blog", "items").to_s
 => "http://localhost/items"

וגם קלוז'ר במימוש של ספריית lambdaisland/uri תואמת להתנהגות של רובי עם הלוכסנים בסוף מילים:

; "http://localhost/items"
(str (uri/join "http://localhost" "blog" "items"))

; "http://localhost/blog/items"
(str (uri/join "http://localhost" "blog/" "items"))

מסקנות -

  1. שימו לב לחתימה של URI/join בשפה שבחרתם, האם אפשר לקבל כמה פרמטרים שרוצים או רק שניים ומה הסדר שלהם.

  2. שימו לב שבחיבור נתיבים ל URL יש לסיים בלוכסן כל נתיב שאתם רוצים שיישאר בתוצאה הסופית.

מכירים עוד מוזרויות של המנגנון בשפות אחרות? אל תתביישו לספר בתגובות או בטלגרם.