من القائمة البريدية:
ستيفان:
أعتقد أنه يجب علينا التخلص من الاستيراد تمامًا وفقط
باستخدام Foo
باستخدام Foo: barالأول يتم تحميل وإنشاء ارتباط لـ Foo ، وجعل عمليات التصدير متاحة كارتباطات "ناعمة" (ما يفعله الاستخدام الآن). يمكن أيضًا تحميل الملف الثاني وإنشاء ارتباط لـ Foo ، وإتاحة الشريط كربط "صلب" (ما يفعله الاستيراد الآن). "
يبدو أن هذا لا يزال يمثل نقطة ارتباك للوافدين الجدد.
سنحتاج أيضًا إلى وظيفة import Foo
بطريقة ما ، حيث تحصل على Foo
ولا شيء آخر
using Foo:
؟
using Foo: Foo
؟
لربط Foo
بوحدة Foo (ولا شيء آخر):
import Foo
لربط Foo
بالوحدة Foo ، x
بـ Foo.x ، y
بـ Foo.y
import Foo: x, y
لربط Foo
بالوحدة النمطية Foo ، وجميع أسماء Foo المصدرة غير مؤهلة:
import Foo: *
قد يكون هذا using
بدلاً من ذلك ، لكنني أشعر أن هذا أكثر بروح import
.
يؤدي هذا أيضًا إلى إزالة التمييز بين إدخال شيء ما في النطاق وإتاحته لتمديد الطريقة. أنا شخصياً أعتقد أن هذا أمر جيد ويجعل نظام الوحدات أكثر قابلية للفهم ، لكنني أردت التأكد من أننا طرحناه.
هناك حجة قوية يجب تقديمها وهي أن البنية التي تجعل جميع الارتباطات المصدرة للوحدة النمطية متاحة يجب أن تجعلها ارتباطات ناعمة ( using
) ارتباطات وليست صلبة ( importall
) روابط. افترض أن الوحدة "أ" تستخدم الوحدة "ب" وتعرف foo(::Any)
. إذا قام إصدار لاحق من الوحدة "ب" بتعريف وتصدير foo(::Any)
، فأنت لا تريد أن يتشابك كل منهما مع الآخر. لا تريد أيضًا أن تحدد الوحدة "ب" foo(::Int)
وأن يكون لديك الوحدة "أ" أحيانًا تستدعي هذه الطريقة بدلاً من الطريقة التي حددتها لأنها أكثر تحديدًا ، أو أن تضطر إلى سرد كافة المعرفات التي تريدها من الوحدة "ب" لتجنب استيراد معرف واحد متضارب.
ولكن إذا كنت قد أدرجت بشكل صريح المعرفات التي تريد استيرادها ، فلن يكون هناك أبدًا سبب لتقديم ربط ناعم. إما أنك لن تحدد طرقًا جديدة للمعرف ، وفي هذه الحالة يكون للارتباطات الصلبة والناعمة سلوكًا متطابقًا ، أو أنك ستحدد طرقًا جديدة لها ، وفي هذه الحالة يكون الربط الناعم معادلاً لعدم الربط وإذا كنت تريد هذا السلوك يجب عليك فقط إزالة المعرف من القائمة.
لذا ، باختصار ، أحب اقتراح StefanKarpinski . من الناحية المفاهيمية ، نحتاج إلى روابط صلبة وناعمة ، ولكن يمكننا الحصول على جميع السلوكيات المفيدة باستخدام كلمة رئيسية واحدة.
أرى وجهة نظرك. في هذه الحالة ، أحب اقتراحك بأن using Foo:
(مع النقطتين ولكن بدون عناصر) يبدو متسقًا من الناحية المفاهيمية. تشير النقطتان إلى أنك ستحد من الرموز التي يجب سحبها ، لكنك لا تسرد أيًا منها.
يبدو الزائدة الفارغة :
مضحكة بعض الشيء ، لكنني أعتقد أن الناس سيعتادون عليها
تكمن مشكلة علامة النقطتين اللاحقة الفارغة في أننا نبحث حاليًا عن اسم في السطر التالي - وبعبارة أخرى ، فإن using Foo:
يعتبر غير مكتمل.
ذات صلة: # 4600
أعلم أن ممارسة Julia الحالية تتمثل في استيراد كل شيء إلى ملف
مساحة الوحدة النمطية الحالية ، لكنني أعتقد حقًا أنه لا يزال هناك
طريقة بسيطة وطبيعية لاستيراد اسم الوحدة فقط.
أعتقد أيضًا أن التحميل الزائد الحالي لاستخدام Foo واستخدام Foo.Bar هو
إشكالية. يبدو داخل Foo ولكن ليس داخل Foo.Bar (ما لم يكن Foo.Bar
وحدة؟)
أعتقد أنه تم تناول هذا الأمر في اقتراح ستيفان
باستخدام Foo: Foo
في يوم الخميس ، 14 أغسطس 2014 ، كتب toivoh [email protected] :
أعلم أن ممارسة Julia الحالية تتمثل في استيراد كل شيء إلى ملف
مساحة الوحدة النمطية الحالية ، لكنني أعتقد حقًا أنه لا يزال هناك
طريقة بسيطة وطبيعية لاستيراد اسم الوحدة فقط.أعتقد أيضًا أن التحميل الزائد الحالي لاستخدام Foo واستخدام Foo.Bar هو
إشكالية. يبدو داخل Foo ولكن ليس داخل Foo.Bar (ما لم يكن Foo.Bar
وحدة؟)-
قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub
https://github.com/JuliaLang/julia/issues/8000#issuecomment -52202142.
kmsquire ولكن ماذا يحدث إذا كانت هناك وحدة Foo داخل وحدة Foo؟ هذا أمر غامض للأسف.
هذا خطأ في التصميم (ويسبب تحذيرًا) ، لذلك لا يهم
تعجبني النسخة التي اقترحها ssfrr فوق الأفضل.
هل هناك اصطلاح أساسي بأن الحزم لها نقطة دخول وحدة واحدة فقط؟ - إلى import Foo
يعني استيراد وحدة Foo
من الحزمة Foo
. يجب أن تكون أي وحدة نمطية أخرى وحدة فرعية من Foo
. مما يعني أن هناك مراسلات ضمنية بين الحزمة Foo و Foo.jl
في العبوة و module Foo
بداخلها.
أطلب b / c وأتساءل عما إذا كان يمكن أيضًا استخدام import
للاستيراد المحلي / النسبي. لنفترض أن المشروع به src/foo.jl
و src/bar.jl
ثم في foo.jl
:
import bar
سوف يستورد من src/bar.jl
. يعد هذا تحسينًا عن استخدام include
لأنه يعمل ضمن نظام الوحدة.
نعم ، من المتوقع أن تكون الحزم ونقاط دخول الحزم والوحدات النمطية فردية. يمكنك كسر هذا الاصطلاح إذا احتجت إلى ذلك ، ولكن ليست هناك حاجة ماسة لذلك نظرًا لأن الوحدات النمطية مخصصة فقط للتسمية وليست وحدات وظيفية. الفكرة التي تطرحها هي # 4600 باستثناء بناء الجملة للاستيراد النسبي هو import .bar
بينما import bar
هو استيراد مطلق.
StefanKarpinski هل يبحث import .bar
بالفعل عن "bar.jl" في الدليل المحلي؟ كان لدي انطباع بأن import .Bar
أشار فقط إلى وحدة فرعية من الوحدة الرئيسية الحالية بالفعل.
تحديث: هذا ما تقترحه في # 4600. آسف.
: +1 :. إذا كنا سنفعل هذا ، فسيكون 0.4 هو الوقت المناسب للقيام بذلك.
: +1: الرجاء المضي قدمًا وتنظيف بعض من هذا (مقابل 0.4!)
بدلاً من وجود آليتين للاستيراد للتمييز بين التمديد أو عدم التمديد ، فلماذا لا يتم تمديد الإشارة في موقع الامتداد نفسه عبر كلمة رئيسية أو تعليق توضيحي في تعريف الوظيفة ، على سبيل المثال تجاوز الكلمة الأساسية قبل الوظيفة؟ مماثل للتعليق التوضيحي @Override
في Java.
هذا له ميزة أن المرء يرى بوضوح أن الوظيفة تتجاوز الأخرى (وبالتالي فهي طريقة)
هذا ممكن بالفعل ،ssagaert. يمكنك القيام بذلك عن طريق كتابة اسم الوحدة بشكل صريح في تعريف الوظيفة (على سبيل المثال ، Base.print(…) = …
) ، ويبدو أنه نمط يتقارب عليه الكثير من الأشخاص. النقطة الشائكة الوحيدة هي أن بناء الجملة لا يعمل مع جميع الأسماء المحتملة (مثل .+
، إلخ).
(جانبا ، يرجى توخي الحذر لإرفاق وحدات الماكرو مع backticks `` لمنع مضايقة مستخدمي GitHub الآخرين).
: +1: إلى اقتراح ssagaert باستخدام @override
، تظهر رسالة الخطأ الأصلية عندما يحاول المرء تمديد طريقة دون استيرادها أولاً كما يلي:
ERROR: error in method definition: function Foo.x must be explicitly imported to be extended
لذا فربما يكون @extend
أكثر ملاءمة؟ أنا لست متحدثًا أصليًا للغة الإنجليزية ، لكن ما أفهمه هو أن _override_ تعني شيئًا مثل: الإلغاء ، أو الإبطال ، أو الإبطال ، أو النفي ، أو الإلغاء ، أو الإلغاء ، أو التوقف ، وما إلى ذلك.
أعتقد أن هذا أكثر وضوحا:
<strong i="13">@extend</strong> Base.show(...) = ...
من:
import Base: show
# ... several lines here
Base.show(...) = ...
@ Ismael-VC Base.show(...) = ...
يعمل بالفعل بدون استيراد أي شيء. import
ضروري فقط إذا كنت تريد show(...) = ...
لتوسيع Base.show
.
كانت كلمة تجاوز @ Ismael-VC مجرد اقتراح. يمكن أن تكون ممتدة أو أي شيء آخر ذي معنى. أيضًا يجب ألا يكون هناك @
منذ ذلك الحين في جوليا وهذا يعني أنه ماكرو ( @Override
يشير إلى Java حيث يكون تعليقًا توضيحيًا).
simonster شكرا لم أكن أعرف ذلك!
ssagaert لذا تقصد كلمة أساسية؟ لقد جربت شيئًا كهذا ولكني ما زلت أمتلك الماكرو فو:
module Extend
export <strong i="9">@extend</strong>
macro extend(x)
mod = x.args[1].args[1].args[1]
met = x.args[1].args[1].args[2]
imp = :(Expr(:import, $mod, $met))
:(Expr(:toplevel, $imp, $(esc(x))))
end
end
أعلم أن هذا ليس عامًا ، ما زلت لا أستطيع عمل تعبير يعيد ما يفعله التحليل:
julia> using Extend
julia> type Foo end
julia> <strong i="13">@extend</strong> Base.show(x::Foo) = Foo
:($(Expr(:toplevel, :($(Expr(:import, Base, :show))), show)))
julia> parse("import Base.show; Base.show(x::Foo) = Foo")
:($(Expr(:toplevel, :($(Expr(:import, :Base, :show))), :(Base.show(x::Foo) = begin # none, line 1:
Foo
end))))
أعتقد أن الماكرو العام والعملي @extend
لن يغير دلالات آلية الاستيراد.
@ Ismael-VC لقد فعلت ولكني أحب "خدعة" mbauman أيضًا.
أعتقد أنه قد يكون من الجيد أن تكون قادرًا على استخدام .
على أنها تعني "هذا". حتى تتمكن من كتابة تعبيرات مثل:
import Base: .
(بمعنى استيراد Base.Base
)
أو
using ..
أنا متأكد من أن ذلك سيتطلب https://github.com/JuliaLang/julia/pull/11891#issuecomment -116098481. ربما يكفي السماح بمسافات قبل .
، لكن ليس بعده ، لحل حالة الغموض؟
أعتقد أن الطلب قد تم إهماله بالفعل. قد يكون من الجيد إضافة تدوين نقطي أكثر مرونة عند استيراد الوحدة بمقدار 1.0 ، لكنني أشك في أننا سنغير أي شيء هنا من خلال تجميد ميزة 0.6
بعد مجموعة من المناقشات حول هذا أمس ، أميل إلى شيء مثل المقترحات في https://github.com/JuliaLang/julia/issues/8000#issuecomment -52142845 و https://github.com/JuliaLang/julia/ القضايا / 8000 # issuecomment -52143609:
using A: x, y # hard imports x and y from A
using A: A # hard imports just the identifier `A`
using A: ... # soft imports all of A's exports
using A # equivalent to `using A: A, ...`
using A.B # A.B must be a module. equivalent to `using A.B: B, ...`
using A: ..., thing1, thing2 # import all exports plus some non-exported things
قد يكون البديل هو الاحتفاظ بـ import
بدلاً من using
:
import A # hard binding for the module `A`
import A: ... # soft bindings for all names exported by `A`
import A: x, y # hard bindings for `x` and `y` from `A`
import A: x, y, ... # equivalent to doing both of the previous two
إن القاعدة العامة التي تحدد ما إذا كان الربط صعبًا أم ناعمًا ستكون بسيطة: أي اسم مطلوب صراحةً يكون ارتباطًا صعبًا ، وأي ارتباط يتم توفيره ضمنيًا يكون ناعمًا.
تحرير: هناك بعض الرغبة في إضافة بعض الاختصارات إلى هذا المخطط لـ import A; import A: ...
وهو تقريبًا ما يفعله حاليًا using A
(الاختلاف الوحيد هو أن using A
يستورد حاليًا A
) ؛ يمكن أن يستمر هذا إما using A
أو import A...
تم اقتراحه.
نعم ، أعتقد أن هذا أيضًا اقتراح جيد. يعود الأمر بشكل أساسي إلى ما إذا كان المرء يفضل using
أو import
.
ملحق ، يمكننا الاحتفاظ بـ using A
كاختصار لـ import A; import A: ...
- إلى جانب التخلص من السلوك الحالي الذي يحتوي كل وحدة نمطية على ارتباط مُصدَّر لنفسها ، وهذا هو سبب أسباب using A
سيكون هناك ارتباط ناعم بـ A
متاح.
سأصاب بخيبة أمل كبيرة إذا كان لا يزال لدينا عدة كلمات رئيسية بعد كل هذا.
يعجبني التماثل بين import
و export
. (كما أشار أحدهم في مكان ما.)
لا يبدو إجراء "عمليات ربط صلبة" دائمًا على أنه الإعداد الافتراضي الأكثر أمانًا من حيث امتداد الطريقة. كان هناك اقتراح مرتبط ولكن منفصل إلى حد ما للمطالبة بتأهيل الوحدة النمطية لتمديد الأسلوب الذي يمكن أن يزيل الحاجة إلى "الارتباطات الصلبة".
هناك حاجة أيضًا إلى روابط صلبة لهذا الغرض:
import Package: x
x = 1 # gives an error
والأهم من ذلك ، أن هذا الاقتراح لن يؤدي دائمًا إلى عمليات ربط صعبة - فقط للأشياء التي تدرجها بشكل صريح. إن طلب قول import
بدلاً من using
لا يضيف الكثير من الأمان.
تأتي السلامة من غالبية الأماكن التي لا تقوم بتمديد الطريقة التي يمكن أن تفلت بشكل جيد من خلال الربط الناعم. أعتقد أنه لا يزال يجب أن يكون لدينا طريقة لطلب ارتباط ناعم معين دون الاضطرار إلى استيراد جميع صادرات الحزمة (أو الحصول على ربط ناعم معين لم يتم تصديره).
هل لا يزال لدينا تحذير بشأن الكتابة فوق الربط المستورد؟
أعتقد أن طلب مؤهل وحدة فكرة جيدة. الآن لمعرفة ما إذا كان يتم تقديم وظيفة أو تمديد طريقة ، يجب عليك إلقاء نظرة على محتويات الحزمة بالكامل للحصول على بيان import A: func
.
هل لا يزال لدينا تحذير بشأن الكتابة فوق الربط المستورد؟
أعتقد أنه في الواقع خطأ الآن.
هناك اقتراح آخر يحافظ على كلتا الكلمتين الرئيسيتين ، لكنه يبسط الأمور قليلاً:
import A: ...
using A:
using A.B
، اطلب A.B
ليكون وحدة ، ووثق أنه اختصار لـ import A.B; import A.B: ...
.بهذه الطريقة ، يمكن إنجاز كل شيء باستخدام import
فقط ، لكن using X
متاح للراحة. سيكون هذا أيضًا من السهل الانتقال إليه بشكل خاص.
راجع للشغل ، يبدو using
غير متناسق كما نشرت هنا . إذا احتفظنا بـ using
، فيجب إعادة تسميته إلى use
إن أمكن.
أعتقد أننا يجب أن نطلب القياس الكمي للوحدة عند توسيع الوظائف لأن معناها أوضح بكثير من نمط الاستيراد ثم التمديد.
نهجي المفضل:
using A: A
import
ونوع الربط الذي يتم إنشاؤهالأشياء التي يجب أن تحدث لتنفيذ https://github.com/JuliaLang/julia/issues/8000#issuecomment -327512355:
using A
للإستيراد الصعب A
using A: x
using A.x
حيث لا يكون x
وحدة فرعيةimport A.x
حيث لا يكون x
وحدة فرعية...
إلى import
يستخدم using A: x
كثيرًا وهو مفيد جدًا. أنت تقول أنك تريد x
في مساحة الاسم الخاصة بك ولكنك لا تريد تمديدها. في import A: x
، أنت تقول أنك تريد أن تكون قادرًا على تمديد x
. هناك تمييز ذو مغزى بين وجود وظيفة متاحة للاستخدام والقدرة على توسيعها.
عند التفكير في الأمر ، أقول إن أكبر مشكلة واحدة هنا هي أن using A.B
يقوم بأمرين: إذا كان B
وحدة نمطية ، فإنه يستورد جميع صادراته ، وبخلاف ذلك فقط الواردات اللينة B
. أعتقد أننا يجب أن نصلح ذلك فقط ، ونجعل using A.B
مسموحًا به فقط للوحدات النمطية ، ولدينا using A: a, b
لاستيراد ارتباطات معينة بسيطة واحدة تلو الأخرى.
أفضل ما إذا كانت هناك طريقة واحدة لكتابة import A: x
بدلاً من أن تكون معادلة لـ import A.x
.
أنا أصوت لـ import A: x
حيث يمكننا أيضًا القيام بذلك ؛ قد يبدو import A: x, y, @z
لكن import A.x, A.y, a.@z
قبيحًا.
هل حذف هذا من 1.0 يعني أنه سيتم ترك كل من using
و import
مقابل 1.0؟ هذا مؤسف بعض الشيء في رأيي.
ماذا عن:
using A
import A: ...
using A.X
( X
عبارة عن وحدة نمطية) يصبح استيراد A.X: ...
using A: X
( X
ليس وحدة نمطية) يصبح import A: X
import A: X
لم يتغير لكن لا يمكنك تمديد X
تلقائيًا (انظر النقطة الأولى)using
هل أفتقد بعض حالة الاستخدام؟ ربما تم اقتراح هذا بالفعل ...
ما يعجبني في أن أكون صريحًا بشأن الوحدة عند التمديد هو أن الامتداد يصبح أكثر محلية. في الوقت الحالي ، عند تمديد إحدى الطرق ، من الشائع وضع الاستيراد بالقرب من الجزء العلوي من الوحدة النمطية (والذي قد يكون في ملف مختلف تمامًا!). عندما يتم حذف الطريقة الممتدة عادة ما يتم نسيان بيان الاستيراد.
أعتقد أن هذا هو نفس اقتراحي أعلاه ، والذي حصل على قدر لا بأس به من الدعم. يريد JeffBezanson حقًا الاحتفاظ بـ using A
على الأقل لسهولة الاستخدام و using A: x
لأنه على ما يبدو (لم يتم بيع هذا الأمر) ، إنها حالة استخدام مهمة لتكون قادرًا على استيراد ارتباط في بطريقة لا يمكنك تمديدها. هناك بعض المقترحات للسير في الاتجاه الآخر واستبدال import
بـ using
لكن لم يحصل أي منهم على الكثير من الجاذبية (يبدو import
أكثر أهمية).
أعتقد أن الاختلاف في:
x
و y
من A
بافتراض أن معنى "الربط الثابت" هو أنه يمكنك تمديده بدون بادئة الوحدة النمطية ، في إصداري لا توجد روابط صلبة. إذا كنت ترغب في التمديد ، فأنت تقوم ببدء الوحدة النمطية حيث تقوم بتمديدها بالضبط. لا توجد عبارات مخيفة import
في ملفات أخرى تغير المعنى سواء كان الشيء امتدادًا أم لا.
و
using A: x
لأنه على ما يبدو (لم يتم بيعي لهذا الأمر) ، من المهم أن تكون قادرًا على استيراد ارتباط بطريقة لا يمكنك تمديدها.
ألا يتم فرض بادئة الوحدة النمطية للتعامل مع ذلك؟ أم أننا نتحدث عن غير وحدات مثل:
module M
x = 1
end
يعطي كلا من import M: x; x = 2
و using M: x; x = 2
نفس رسالة التحذير لذلك لا أرى سبب المشكلة ...
يبدو أن الاحتفاظ بـ using A
لسهولة أكثر من import A: ...
مبالغ فيه بعض الشيء في رأيي.
ألا يتم فرض بادئة الوحدة النمطية للتعامل مع ذلك؟
نعم؛ إذا كان عليك تأهيل الوظائف لتمديدها ، فلن تكون هذه النقطة ذات صلة.
الاستمرار في استخدام "أ" لسهولة الاستيراد "ج": ... يبدو مبالغًا فيه بعض الشيء في رأيي.
أرى الأمر في الاتجاه المعاكس. جعل الناس يتحولون من using A
(وهو أمر لطيف وقصير وكلنا معتادون على ذلك) إلى import A: ...
فقط لتلبية مطلب اصطناعي يفيد بأن هناك كلمة رئيسية واحدة مفرطة.
من قراءة الموضوع ، يبدو أن القيمة الرئيسية في وجود كلمتين رئيسيتين هي التمييز بين الارتباطات التي يمكن تمديدها أم لا (الربط الثابت). مع وضع ذلك في الاعتبار ، أعتقد أن هناك حلين قابلين للتطبيق:
using
و extending
في هذه الحالة. import
جيد ، لكن extending
يجعل سبب وجود الكلمة الرئيسية الثانية واضحًافي كلتا الحالتين ، أقترح أن يكون using
كما هو الآن مع إضافة أحد العناصر التالية لربط الوحدة فقط Foo
:
using Foo: nothing
(يعمل الآن)using Foo: Foo
(يعمل الآن)using Foo:
(يمكن إضافته لاحقًا)ثم يجب أن يتصرف extending
مماثلاً لـ using
مع الاختلاف الوحيد هو أنه يمكنك تمديد الارتباطات التي يتم إحضارها بـ extending
، وربما عدم السماح extending Foo
بحيث يكون أن تكون صريحًا.
| | إتاحته (باستخدام) | جعل قابلة للتمديد (استيراد) |
| ------------------- | -------------------------- | ---------------------- |
| الوحدة فقط | using module: module
أو using module: nothing
| import module
|
| كل شيء يتم تصديره | using module
(أثر جانبي: يتصرف مثل import module
أيضًا) | ؟ |
| أشياء معينة | using module: x,y
| import module: x,y
|
| | إتاحته (باستخدام) | جعل قابلة للتمديد (استيراد) |
| ----------------- | ------------------------ | -------------------------- |
| الوحدة فقط | using module
| import module
|
| كل شيء يتم تصديره | using module: *
| import module: *
|
| أشياء معينة | using module: x,y
| import module: x,y
|
الشيء الجميل في هذا هو أن استيراد المزيد يتوافق مع كتابة المزيد. أي أن تبدأ بـ using module
وإذا كنت تريد استيراد متغير مباشرة إلى مساحة الاسم ، فأنت تضيف : x
بدلاً من إزالة nothing
أو module
. وهذا يعني أيضًا أن أقصر شيء تكتبه يتضمن الأقل.
يمكنك أيضًا عمل using: *,x
لإتاحة كل ما يتم تصديره و x
الذي لم يتم تصديره.
| | إتاحته (باستخدام) | جعل قابلة للتمديد (استيراد) |
| ----------------- | ------------------------ | -------------------------- |
| الوحدة فقط | using module:
| import module:
|
| كل شيء يتم تصديره | using module: *
| import module: *
|
| أشياء معينة | using module: x,y
| import module: x,y
|
احتفظ بحوالي using module
و import module
مع السلوك الحالي للتوافق مع الإصدارات السابقة ولكن قم بإهماله.
FelixBenning : import Module
حاليًا لا (من تلقاء نفسه) يجعل أي شيء قابل للتمديد أكثر من using Module
، إنه يقوم فقط بتحميل الكود وإحضار Module
(ولا شيء آخر) إلى مساحة الاسم .
فقط لتعكس ما قلته في Slack وحتى لا يتلاشى في فتحة Slack:
لا أعتقد أن جعل using X: *
هو الخيار الافتراضي لجعل كل شيء مُصدَّر متاحًا مقابل using X
فقط سيجعل الناس بالضرورة أكثر حذرًا مما يستوردونه. أعلم ، أن الإشارة إلى كيفية قيام الآخرين بذلك يعتبر شكلًا سيئًا ، لكن Python تحتوي بشكل أساسي على تلك الدلالات مع import X
و import X: *
، ومع ذلك فإن نظامهم الإيكولوجي مليء بواردات النجوم 🤷♂️ (و من المعروف أنهم يكرهون ذلك) لا أعتقد أن النص الأطول بشكل هامشي الذي يجب على المرء كتابته يمنع الناس من فعل ما يعتبرونه الأكثر ملاءمة: فقط قم باستيراد / استخدام كل شيء ودع المترجم يكتشف ذلك. لهذا السبب أشعر بالقلق من الرصاصة السحرية لجعل الناس يكتبون هذا النجم بشكل صريح.
علاوة على ذلك ، import module: *
و using module: *
غير متاح للمعنى المقترح. لها معنى بالفعل حيث أن *
هو معرف Julia صالح ويمكن استيراده / استخدامه تمامًا مثل +
أو الكلمة mul
.
tpapp إما أنني قد أسأت فهم الوثائق مرة أخرى ، أو أن import Module
يجعل Module.x
قابل للتمديد. بينما using Module: x
لا يجعل Module.x
قابل للتمديد. لذلك فإن import Module
يجعل شيئًا ما متاحًا للتمديد و using Module
يفعل ذلك أيضًا ، ولهذا السبب لاحظت أن الاستخدام له هذا التأثير الجانبي.
(من https://docs.julialang.org/en/v1/manual/modules/)
لا يهم حقًا أي واحد منا على حق - في كلتا الحالتين يكون الوضع الحالي فوضويًا بشكل واضح إذا لم نتمكن حتى من معرفة ما يفعله كل شيء.
mbauman نقطة جيدة - لقد نسيت ذلك. لا أهتم حقًا بـ *
فقط بنية امتلاك using
تعكس الأشياء import
مع اختلاف الاستيراد مقابل استخدام ما إذا كانت الأشياء تصبح قابلة للتمديد أم لا. لذلك إذا كان هناك رمز أكثر ملاءمة - all
، __all__
، everything
، exported
، ...؟ أنا مستعد تماما لها. أعتقد فقط أنه من المحتمل أن ينعكس استيراد المزيد من خلال كتابة المزيد.
ولكن إذا كنت لا تريد ذلك على الإطلاق ، فيمكنك بالطبع أيضًا اختياره
| | إتاحته (باستخدام) | جعل قابلة للتمديد (استيراد) |
| ----------------- | ------------------------ | -------------------------- |
| الوحدة فقط | using module: module
| import module: module
|
| كل شيء يتم تصديره | using module
| import module
|
| أشياء معينة | using module: x,y
| import module: x,y
|
أو
| | إتاحته (باستخدام) | جعل قابلة للتمديد (استيراد) |
| ----------------- | ------------------------ | -------------------------- |
| الوحدة فقط | using module
| import module
|
| كل شيء يتم تصديره | using module: module
| import module: module
|
| أشياء معينة | using module: x,y
| import module: x,y
|
ولكن مهما كانت النتيجة النهائية ، يجب أن تكون متسقة. وفي الوقت الحالي ، الأمر ليس كذلك.
using A
يجعل A.f
قابل للتمديد ، _not_ f
بمفرده. من أجل تمديد _just_ f
بدون التصريح عن الوحدة التي تريد توسيعها ، يجب أن تصل إلى import A: f
صراحة. وإلا فلا يزال يتعين عليك تأهيله.
تحقق مما يلي لمعرفة دلالات using
julia> module A
export f
f() = "no args in A"
end
Main.A
julia> f()
ERROR: UndefVarError: f not defined
Stacktrace:
[1] top-level scope at REPL[2]:1
julia> using .A
julia> f()
"no args in A"
julia> f(1)
ERROR: MethodError: no method matching f(::Int64)
Closest candidates are:
f() at REPL[1]:3
Stacktrace:
[1] top-level scope at REPL[5]:1
julia> f(x) = "one arg where?"
ERROR: error in method definition: function A.f must be explicitly imported to be extended
Stacktrace:
[1] top-level scope at none:0
[2] top-level scope at REPL[6]:1
julia> A.f(x) = "one arg where?"
julia> f(1)
"one arg where?"
وهذا بالنسبة لدلالات import
:
julia> module A
export f
f() = "no args in A"
end
Main.A
julia> f()
ERROR: UndefVarError: f not defined
Stacktrace:
[1] top-level scope at REPL[2]:1
julia> import .A
julia> f()
ERROR: UndefVarError: f not defined
Stacktrace:
[1] top-level scope at REPL[4]:1
julia> A.f()
"no args in A"
julia> f(1)
ERROR: UndefVarError: f not defined
Stacktrace:
[1] top-level scope at REPL[6]:1
julia> A.f(1)
ERROR: MethodError: no method matching f(::Int64)
Closest candidates are:
f() at REPL[1]:3
Stacktrace:
[1] top-level scope at REPL[7]:1
julia> f(x) = "one arg where?"
f (generic function with 1 method)
julia> f(1)
"one arg where?"
julia> A.f(1)
ERROR: MethodError: no method matching f(::Int64)
Closest candidates are:
f() at REPL[1]:3
Stacktrace:
[1] top-level scope at REPL[10]:1
julia> A.f(x) = "one arg where in A"
julia> A.f(1)
"one arg where in A"
FelixBenning : نعم ، أعتقد أنك أسأت فهمك. FWIW ، أعتقد أن "... يجعل Foo.x
قابل للتمديد" هي طريقة مربكة للتعامل مع التمييز --- يمكنك دائمًا تحديد طرق لأسماء الوظائف المؤهلة بالكامل. ما يحدث مع using Foo: x
هو أنه لن يتم إحضار Foo
نفسه إلى مساحة الاسم.
بالمناسبة ، عند إعادة قراءة هذا الموضوع ، أتساءل عما إذا كان # 25306 قد أوصلنا إلى نوع من المستوى المحلي الأمثل ، والقرار الوحيد المتبقي هو ما إذا كنا بحاجة إلى عمليات استيراد غير قابلة للتوسيع في مساحة الاسم (حاليًا using Foo: f
). ولكن نظرًا لكسر هذا الأمر ، فقد يستفيد الفصل اليدوي من إعادة الكتابة في هذه الأثناء ، يجد العديد من المستخدمين الأمر برمته محيرًا.
هذه هي الطريقة التي سأتعامل بها مع الوضع الراهن في المستندات:
using M
بتحميل الوحدة ، وإحضار M
ورموزها المصدرة إلى مساحة الاسم. هذه هي الحالة الوحيدة التي تكون فيها الصادرات مهمة.M
، يمكنك استخدام الأسماء المؤهلة مثل M.y
لـ (أ) الوصول إلى الرموز غير المصدرة و (ب) إضافة طرق إلى الوظائف ، بغض النظر عما إذا كانت مُصدرة أم لاM.f
، أو ...import M: f
، إذًا يمكنك فقط استخدام f
عند تحديد الطرق.import M
و using M: x
لجلب M
أو x
( وليس M
) ، على التوالي ، في مساحة الاسم ، على التوالي. يحب بعض الأشخاص استخدام هذه النماذج في كود الحزمة للتأكد من أن مساحات الأسماء الخاصة بهم تظل نظيفة (اربط أدلة الأنماط ذات الصلة هنا).يعكس الطلب بشكل أو بآخر حالات استخدام مصادفة مع استخدام أكثر تقدمًا. كل ما سبق ينطبق على الوحدات الفرعية ، مع M.A
بدلاً من M
.
ماذا عن هذا:
using M
ينقل M
إلى النطاقusing M: x
يجلب M.x
إلى النطاق (مثل x
)using M: ...
جميع الرموز المصدرة لـ M
إلى النطاقusing M: x, ...
جميع الرموز المُصدَّرة M
إلى النطاق وأيضًا x
(والتي قد تكون غير مُصدَّرة)import
. تحتاج إلى استخدام الاسم المؤهل لتوسيع وظيفة. (أو using M; const foo = M.foo
مثلما يمكن أن يفعله المرء الآن.)M
وحدة فرعية ، على سبيل المثال Foo.Bar
و x
يمكن أيضًا أن يكون x as y
بالمعنى الحالي.أو نستخدم import
بدلاً من using
مما يجعل هذا يساوي https://github.com/JuliaLang/julia/issues/8000#issuecomment -355960915.
استخدام شائع جدًا (خاصة في "البرامج النصية" ، ولكن أيضًا في حزم لأنماط معينة)
using Foo, Bar, Baz
والاعتماد فقط على الرموز المصدرة. سيكون هناك بعض الفوائد من إبقاء هذا الأمر أبسط ، ربما بهذه البساطة كما هو الآن.
tpapp
أظن أنك فهمت بشكل خاطئ. FWIW ، أعتقد أن "... يجعل Foo.x قابل للتمديد" هي طريقة مربكة للتعامل مع التمييز - يمكنك دائمًا تحديد الأساليب لأسماء الوظائف المؤهلة بالكامل.
حسنًا ، هل يمكنني تمديد Foo.x
بعد using Foo: x
؟ لأنه إذا كانت الإجابة بنعم ، فلن تكون المستندات كاملة (انظر لقطة الشاشة الخاصة بي). إذا لم يكن الأمر كذلك ، فقد فهمت تمامًا كيفية عمل هذه العبارات ومن الواضح تمامًا أن import Foo
فعل شيئًا لجعل Foo.x
قابل للتوسيع. لذلك فهو يجعل حرفيا Foo.x
متاحًا للتمديد. بكل معاني هذه الكلمات. من المؤكد أنها لا تجعل x
متاحًا للتمديد ، ولكن هذا هو ما يعنيه import Foo: x
حسنًا ، هل يمكنني تمديد
Foo.x
بعدusing Foo: x
؟
ليس إلا إذا قمت بإحضار Foo
إلى مساحة الاسم بطريقة ما (على سبيل المثال ، using Foo
).
لقد فهمت تمامًا كيف تعمل هذه العبارات
لست متأكدًا تمامًا من هذا - ومع ذلك ، إذا كانت لديك أسئلة حول الوحدات ومساحات الأسماء ، فيرجى التفضل باستخدام منتدى الخطاب.
من الواضح تمامًا أن
import Foo
فعل شيئًا لجعلFoo.x
قابل للتوسيع
فقط بمعنى أنه يجب أن تكون قادرًا على الإشارة إلى وظيفة بطريقة ما باستخدام اسم مؤهل قبل إضافة طرق إليها.
ثم الوثائق ليست كاملة
أعتقد أنه ، بطريقة غريبة. في هذا المثال بالذات ، إذا كان كل ما تفعله هو using MyModule: x, p
؛ ثم لا توجد طرق متاحة للتمديد ، وبالتالي فإن الجدول صحيح.
أوافق على أنه يمكن كتابته بشكل أفضل ، كما قلت أعلاه. كثير من الناس غير المعتادين على مساحات الأسماء يجدونها مربكة. و TBH ، السيرك كله using
/ import
هو أمر محير إلى حد ما ، ومن هنا جاءت هذه المشكلة.
tpapp
حسنًا ، هذا هو الشيء: ليس من الواضح تمامًا أنه يمكنك تمديد كل وظيفة بالاسم الكامل إذا كانت الوحدة في مساحة الاسم. أعلم أن هذا هو السلوك الحالي ، لكنني لا أعتقد أن أي شخص لا يعرف ذلك سيفترض ذلك بالفعل. خاصة وأن التواجد في مساحة الاسم لا يعني دائمًا أنه قابل للتمديد أيضًا. إذا فعلت ذلك using module:x
فلا يمكنني تمديد x
. بينما يمكنني تمديد x
، إذا استخدمت import module:x
. لذلك فمن المعقول أن يكون الفارق بين using
و import
هو ما إذا كان بإمكانك تمديد الوظائف المستوردة أم لا.
باستخدام هذا الافتراض سيكون من المنطقي ، إذا كان using module
سيسمح فقط باستخدام module.x
لكن لن يسمح بتمديد module.x
. بينما import module
سيسمح بتمديد module.x
. لذلك إذا أخذت هذا الافتراض وقرأت التوثيق ، ستجد أن شيئين خاطئين بشأن ذلك.
using module
بتمديد module.x
. لذلك من المتعلمين من منظور المتعلمين using module
له تأثير جانبي ، أنه يعمل أيضًا مثل import module
- أي أنه يجعل module.x
قابل للتمديد. وجعل الأشياء قابلة للتمديد هو شيء import
، وليس شيء using
import
، فإن using
لا يجعل فقط module
متاحًا ، بل كل شيء فيه.لذلك هذا ما حاولت تمثيله على طاولتي. إذا تم استخدام كلمتين مختلفتين (استيراد / استخدام) ، فيجب عليهم فعل شيئين مختلفين ويجب أن يكون ذلك واضحًا تمامًا. إذا كان using
يسمح أحيانًا بالتمديد وفي أحيان أخرى لا يكون هذا سلوكًا غير متوقع.
البديل الجيد هو إزالة الاستيراد تمامًا كما يقترح martinholters . لا يمكنك ببساطة استخدام كلمتين بشكل عشوائي لأشياء معينة. إذا كان import
يعني جعل الأشياء قابلة للتمديد عند استيراد وظائف معينة ، بينما using module: foo
لا يسمح بذلك ، فيجب أن يحدث نفس السلوك عندما تقوم فقط بتضمين module
في مساحة الاسم.
فقط لأنك تستطيع تمديد كل شيء باسمه الكامل في الوقت الحالي إذا كانت الوحدة في مساحة الاسم ، فهذا لا يعني أن هذا أمر واضح أو مباشر.
إما أن يكون التواجد في مساحة الاسم كافيًا ، فيجب أن أكون قادرًا أيضًا على تمديد x
إذا قمت بتضمينه في مساحة الاسم مع using module:x
أو أن التواجد في مساحة الاسم ليس كافيًا ، وبعد ذلك يجب علي أيضًا لن تكون قادرًا على تمديد module.x
عند استخدام الأمر using
.
أو الخيار الثالث: لا يوجد import
وعليك ببساطة تمديد الوظائف باسمها الكامل طوال الوقت.
ليس من الواضح على الإطلاق أنه يمكنك تمديد كل وظيفة بالاسم الكامل إذا كانت الوحدة في مساحة الاسم.
أوافق ، ولهذا أجادل من أجل إعادة كتابة المستندات. ومع ذلك ، هذا عرضي للقضية الحالية. سيكون من الأفضل الاحتفاظ (1) بمقترحات لتحسين التوثيق حول API الحالي و (2) مقترحات لإعادة تصميمها بشكل منفصل ، حتى لو كان الاثنان مرتبطين إلى حد ما. أخطط لعمل علاقات عامة لـ (1) قريبًا.
tpapp لا يمكنك توثيق أي شيء لا معنى له بطبيعته. أي من هذه الوثائق غير صحيحة:
using module:x
لا يسمح لك بتمديد x
)using
و import
" (خطأ لأنه بالنسبة للأسماء الكاملة ، يكفي في الواقع أن تكون في مساحة الاسم - إيقاف ذلك كان اقتراحي كافيا)import module:x
للتوقف عن الوجود ليكون الحقيقة الكاملة - اقتراح martinholters )أي من هؤلاء سيكون مقبولا. لكن لا شيء من هذه حقيقة واقعة. في الواقع حاليًا ، هناك كلمتان مختلفتان تستخدمان "لاستيراد الأشياء" ولكنهما لا تمتلكان في الواقع حالة استخدام مميزة. إنه مثل حلقة for
تتصرف أحيانًا مثل حلقة while
إذا قمت بالتكرار على القيم المنطقية. لن يجعل أي قدر من الوثائق ذلك غير مربك
لا يمكنك توثيق شيء لا معنى له بطبيعته.
واجهة برمجة التطبيقات للوحدات النمطية الحالية محددة جيدًا ، لذا يمكن توثيقها (إنها كذلك بالفعل ، أعتقد أنها يجب أن تكون أفضل).
أي من هذه الوثائق غير صحيحة:
يرجى أن تكون لطيفًا حتى تنتظر العلاقات العامة الخاصة بي (أو الخاصة بشخص آخر) والتعليق على النص الفعلي الذي سيكون هناك. إن افتراض التوثيق الافتراضي ثم الادعاء بأنه غير صحيح هو مجرد إضافة ضوضاء إلى هذه المناقشة.
tpapp ربما كان يجب أن أقول ،
لا يمكنك توثيق أي شيء بطريقة غير مربكة لا معنى لها بطبيعتها
أعني إلى حد ما الرمز هو كل الوثائق التي تحتاجها بشكل صحيح؟ ما الخطأ فى ذلك؟ الوقت المستغرق لهضمه. ولا أرى حاليًا طريقة مختصرة لوصف كيفية عملها ، لأنها مليئة بالاستثناءات. الاستثناءات التي لا ينبغي أن تكون موجودة في المقام الأول.
هل حقًا لا ترى ما أحاول أن أنقله؟
أعتقد أن هناك اتفاق عام على أن الوضع الحالي معقد بلا داع وغير موثق بشكل كاف. ومما لا شك فيه أن تبسيط الآليات سيجعل عملية التوثيق أسهل. لكن مثل هذا التبسيط سينهار ، لذلك لا يمكن القيام به قبل الإصدار 2.0. إذن ، هل وجهة نظرك هي أن تحسين التوثيق قبل ذلك لن يكون منطقيًا؟ ثم أختلف. أرى مسألتين منفصلتين: التبسيط الذي يتم إجراؤه مع الإصدار 2.0 (الذي تدور حوله هذه المشكلة) والذي سيشمل (نأمل) تحديثات الوثائق الضرورية وتحسين توثيق الأعمال الحالية التي يبدو أنها من خلال قراءة هذا الموضوع تبدو مطلوبة بشدة ولكنها مشكلة أخرى .
بعد إجراء # 38271 ، أعتقد أن الأسئلة المعلقة
Foo.bar() = ...
) ،using Foo: bar; bar() = ...
)import Foo: bar; bar() = ...
)using Foo
جميع الرموز المصدرة في Foo
إلى النطاق ، import Foo
فقط الوحدة ( الوضع الراهن )using Foo: ...
أو بناء جملة آخر مشابه ، ثم using Foo
فقط الوحدة.سيسمح (1 | 2) & 2 بالتوحيد في كلمة رئيسية واحدة ، إما using
أو import
، بتكلفة فقدان سطر واحد
using LinearAlgebra, Random, StaticArrays
لست متأكدًا من أن الأمر يستحق ذلك ، حتى بدون التفكير في التغيير المفاجئ.
هذه ليست واحدة من تلك المشكلات التي تقدم حلاً نظيفًا فاته التصميم الأصلي للتو ؛ هناك مقايضات. سأنتظر وأرى ما إذا كان بإمكان التوثيق الأفضل تحسين تجربة المستخدم مع الحفاظ على الإعداد الحالي (1.0).
بالنسبة إلى الإصدار 2.0 ، أعتقد أن مجرد تنظيف بناء الجملة ليكون أكثر اتساقًا ووصفًا لما يحدث بالفعل سيكون أمرًا رائعًا. شيء مثل:
| قبل | بعد |
| - | - |
| using Foo
| useall from Foo
|
| import Foo
| use Foo
|
| using Foo: a
| use a from Foo
|
| import Foo: a
و import Foo.a
| extend a from Foo
|
التعليق الأكثر فائدة
يعجبني التماثل بين
import
وexport
. (كما أشار أحدهم في مكان ما.)