Less.js: السماح للخلطات ذات المعلمات كمجموعات قواعد منفصلة لتشكيل "لامدا"

تم إنشاؤها على ٤ نوفمبر ٢٠١٤  ·  118تعليقات  ·  مصدر: less/less.js

يبدو أن LESS حاليًا يدعم فقط مجموعات القواعد "الصافية" لتمريرها كوسائط mixin أو تخزينها في متغيرات كمجموعات قواعد منفصلة.

أقترح توسيع هذا الدعم لدمج الخلطات ذات المعلمات ، مما يمنح بشكل أساسي أقل القدرة على العمل مع لامدا.

على سبيل المثال
يمكن للمرء أن يكتب

.list {
  .forEach(foo bar baz, (<strong i="9">@item</strong>, @index) {
    <strong i="10">@i</strong> : (<strong i="11">@index</strong> + 1);
    > li:nth-child(@{i}):before {
      content : "@{item}";
    }
  });
}

حيث يتم تعريف .forEach على أنه

.forEach(<strong i="16">@list</strong>, @lambda) {
  <strong i="17">@n</strong> : length(@list);

  .for(0)
  .for(@index) {}
  .for(@index) when (<strong i="18">@index</strong> < @n) {
    @lambda(extract(<strong i="19">@list</strong>, @index), @index);
    .for(<strong i="20">@index</strong> + 1);
  }
}

من شأن دعم Lambda mixin أيضًا أن يحل المشكلات المتكررة مع وسيطات إرجاع الوظيفة والاختراق القبيح حيث "تنبثق" المتغيرات إلى النطاق الأصلي إذا كانت المتغيرات المذكورة غير محددة بعد في النطاق الأصلي المذكور.

يمكن أن تصبح الممارسة المقترحة هي اعتماد أسلوب البرمجة المستمر ؛ تمرير "قيم الإرجاع" إلى مزيج لامدا للاستمرار في أسفل سلسلة النطاق. هذا النوع من الآلية أكثر شفافية للمستخدمين ، وأقل هشاشة من خلال تجنب المشكلات المتعلقة بتضارب الأسماء المتغيرة المحتملة ويتناسب بشكل أفضل مع نماذج البرمجة الوظيفية الشاملة التي بنيت عليها بنية LESS.

[تعديل]
بعد إلقاء نظرة على الطريقة التي يتم بها تنفيذ القواعد والمكالمات المنفصلة في AST ، أعتقد أن هناك القليل جدًا من الحاجة إلى الحدوث لإنجاح هذا الأمر. حتى في الجانب المحلل اللغوي للأشياء ، يبدو من السهل جدًا تحليل كتلة اختيارية mixin.args قبل blockRuleset في دالة المحلل اللغوي detachedRuleset وتمرير الوسيطات إلى tree.DetachedRuleset مثيل العقدة. (يجب تمديد tree.DetachedRuleset مع تقييم المعلمات من tree.mixin.Definition ، بالطبع.)

feature request medium priority needs decision

التعليق الأكثر فائدة

@ $ يعمل !؟ لا يوجد لدي فكرة! اعتقدت أنه تم إلغاء! هذا يجعلني سعيدة جدا!

ها ، نعم ، لقد تراجعت في إصلاحات الأخطاء قبل أن أفرج عن الإصدار 3.5. ^ _ ^

ال 118 كومينتر

الاختراق القبيح حيث "تطفو" المتغيرات على نطاق الوالدين

فقط في حال لم يكن هذا اختراقًا بشعًا ولكنه وسيلة لغوية محددة جيدًا.
(لا يمكنني أيضًا الحصول على فكرة حل "مشكلات النطاق الأعلى" باستخدام "ميزة تمرير معلمة السلسلة السفلية" ، فهذه لا تبدو مرتبطة ، أليس كذلك؟ ولكن حسنًا ، لا تهتم ، تظل الميزة مفيدة بغض النظر عن من هذا على أي حال)


حسنًا ، في كلتا الحالتين تكون الفكرة نفسها كاشفة تمامًا والمشكلة الوحيدة هي بناء جملة غامض ، لاحظ:

<strong i="11">@a</strong>: {1: 1};      // OK, ruleset
<strong i="12">@b</strong>: (@a);        // OK, set <strong i="13">@b</strong> to <strong i="14">@a</strong>
<strong i="15">@c</strong>: (@a) (@b);   // OK, array/list
<strong i="16">@d</strong>: (@a) {2: 2}; // ?!, array or unnamed ruleset with one parameter?
// same goes if this to be used as a mixin arg

في اللغات الأخرى مع هذه التسهيلات ، يتم حل هذه المشكلة باستخدام بعض الكلمات الرئيسية / عوامل التشغيل المحددة التي تسبق مثل lambda (على سبيل المثال [] في C ++ أو function فقط في JavaScript).

فقط في حال لم يكن هذا اختراقًا بشعًا ولكنه وسيلة لغوية محددة جيدًا.

عندما أذكر أنه "اختراق" ، أعني على وجه التحديد أنه يبدو مخترقًا في تصميم اللغة الحالية (لتسهيل قيم الإرجاع كإضافة لاحقة) ، بدلاً من شيء تم التفكير فيه مسبقًا. لا أعني أن الكود الفعلي منخفض الجودة. فعلا؛ تم عمل المحلل اللغوي LESS و AST بشكل جيد. (غيض من القبعة لذلك).

ومع ذلك ، فإن حقيقة أنها محددة جيدًا ومصممة جيدًا لا تجعلها أقل قبحًا عند استخدامها. إنها ميزة لغوية تتعارض تمامًا مع الحدس بالنسبة لمعظم الناس ، حيث لا توجد لغة سائدة أخرى تفعل ذلك.

المشكلة الوحيدة هي بناء الجملة الغامض
في اللغات الأخرى مع مثل هذه التسهيلات ، يتم حل هذه المشكلة ببعض الكلمات الرئيسية / عوامل التشغيل المحددة التي تسبق لامدا

هل يمكنني اقتراح <strong i="12">@a</strong>: (@b) => { b : b } ؟
إنه يذكرنا بمندوبي lambda في لغة C # وتدوين سهم JavaScript ES6 Harmony للوظائف ذات النطاق المعجمي المحفوظ. شريطة أن تضع مجموعات قواعد منفصلة في رأس الأنواع التي يحاول المحلل اللغوي تطبيقها على التعبيرات (التي أعتقد أنها كذلك بالفعل) ، يجب أن ينتج عن ذلك تحليل حتمي بدون أي غموض.

وإذا أردت _ حقًا_ أن يكون لديك قائمة برمز => صريح هناك ، حسنًا ؛ هناك دائمًا ~"=>" فتحة هروب. (ليس الأمر كما لو أنه ليس لديك بالفعل هذه المشكلة مع calc() إلى حد ما.)

بدلاً من شيء تم التفكير فيه مسبقًا.

(على الرغم من أننا ننتقل بسرعة بعيدًا عن الموضوع - نعم ، لم يكن هذا شيئًا يُفكر فيه في الأيام القليلة السابقة ، لكنه لا يزال حتى اليوم _ الطريقة الوحيدة "للعودة" لشيء ما في "أقل" (نظرًا لأن مرفق "الوظيفة" لا يزال مهملاً إلى حد ما ، على الرغم من أن الأمر برمته لا يقتصر في الواقع على إعادة المتغيرات). لذلك أصر على :) أن "تسرب النطاق الأم" لا علاقة له بأحرف لامدا ، ففي النهاية لا تقوم حيوانات لامدا بإرجاع أي شيء على الإطلاق. والباقي قصة أخرى غير ذات صلة).


<strong i="10">@a</strong>: (@b) => { b : b } - نعم ، يمكن أن يكون شيئًا كهذا (على الرغم من أنني شخصيًا لا أحب => :)

وفقًا للمناقشة التي جرت في # 1943 ، والمتعلقة أيضًا بتمرير الخلطات حسب المرجع (المشكلة رقم؟) ، أود أن أقترح بناء الجملة التالي:

.mixin(@args) {
    box-shadow+: <strong i="6">@args</strong> black;
}
a {
    each(10px 10px, -20px -20px, .mixin);
}

...يساوي...

.mixin(@args) {
    box-shadow+: <strong i="10">@args</strong> black;
}
<strong i="11">@list</strong>: 10px 10px, -20px -20px;
a {
    each(<strong i="12">@list</strong>, .mixin);
}

...يساوي...

<strong i="16">@list</strong>: 10px 10px, -20px -20px;
a {
    each(<strong i="17">@list</strong>, (@args) {
      box-shadow+: <strong i="18">@args</strong> black;
    });
}

ومع ذلك ، لا يوجد سبب يمنعك من استخدام نفس التركيبة للمزيجات التي يحددها المستخدم: .for(<strong i="21">@list</strong>, .mixin); وافعل ما تريد باستخدام معلمات list / mixin.

لكي تكون دقيقًا ، يعد هذا امتدادًا لمزيج / معلمات ، وليس مجموعات قواعد منفصلة ، وقد تمت مناقشة تمرير الخلطات حسب المرجع في مكان آخر (على الرغم من أنني لم أجدها ببحث موجز).

وقد تمت مناقشة تمرير mixins بالإشارة في مكان آخر (على الرغم من أنني لم أتمكن من العثور عليها ببحث موجز).

تم ذكره في https://github.com/less/less.js/issues/965#issuecomment -18462037 ثم تمت مناقشته بمزيد من التفاصيل https://github.com/less/less.js/pull/1648#issuecomment 33859876 والتعليقات التالية.

لكل مناقشة منفصلة مع @plugin ، يبدو هذا الآن كمرشح مثالي للإغلاق لصالح وظيفة محددة بواسطة المستخدم عبر @plugin .

أيضًا ، هذا وثيق الصلة بـ # 1505 الذي علقت عليه للتو ، لأننا نعرض تمرير قائمة CSS إلى وظيفة مخصصة.

يبدو هذا الآن كمرشح مثالي للإغلاق لصالح وظيفة محددة بواسطة المستخدم عبر @plugin

لاحظ أنه لا يمكنك حاليًا تمرير معرّفات مثل .mixin إلى دالة (لا يسمح بها المحلل اللغوي) ولا يمكنك استدعاء دالة بدون تعيين نتيجتها إلى شيء ما ... من المستحيل تنفيذ مثل each عبر البرنامج المساعد.

لذا ، لا ، في الوقت الحالي من المستحيل ببساطة تنفيذ كلٍّ من هذا عبر المكوِّن الإضافي.

أوه. اللعنة. Welll .... ألا يبدو مرشحًا جيدًا لإضافة المزيد من المرونة للمكونات الإضافية؟ ما أعنيه هو ، إنها حالة استخدام محدودة ، وأعتقد أننا تحدثنا عن حالات الاستخدام الضيق كمرشحين للمكونات الإضافية التي يحددها المستخدم. أو الإضافات الأساسية الاختيارية (التي لم يتم تعريفها بعد).

لذا ، بالنسبة لي ، إذا حدث هذا ، فهو إما توسيع النواة بطريقة أو بأخرى. قد يكون أحدهما خاصًا بحالة الاستخدام هذه ، والآخر هو توسيع المكونات الإضافية لدعم سيناريوهات مثل حالة الاستخدام هذه.

@ سبع مراحل كحد أقصى
لذا ، لا ، في الوقت الحالي من المستحيل ببساطة تنفيذ كلٍّ من هذا عبر المكوِّن الإضافي.

أوه ... لن أكون متأكدًا جدًا من ذلك.

أوه ... لن أكون متأكدًا جدًا من ذلك.

نعم ، ولكن في مثالك ، يبدو أنك تقوم بحل جزئي فقط مع المكون الإضافي ، ثم تقوم بالجزء الآخر في مزيج متكرر. كان سؤالي بشكل أساسي إذا كان بإمكان البرنامج المساعد القيام بذلك (من أحد الأمثلة أعلاه:

<strong i="8">@list</strong>: 10px 10px, -20px -20px;
a {
   <strong i="9">@plugin</strong> "awesome-list-functions-which-contains-each";
    each(<strong i="10">@list</strong>, (@args) {
      box-shadow+: <strong i="11">@args</strong> black;
    });
}

بناءً على جوهرك ، يبدو أنك توافق على @ Seven-stage-max. رقم؟

يبدو أنك تقوم بحل جزئي فقط مع المكون الإضافي

يمكنني أيضًا وضع بنية الحلقة في الوظيفة الفعلية. اخترت عدم القيام بذلك ، لتوضيح أنه يمكنك الحصول على وظيفة مفوض لامدا كاملة فقط من خلال ربط المتغيرات في نطاق مجموعة القواعد المنفصلة.

حقيقة؛ تحقق من نفس الجوهر مرة أخرى. لقد قمت للتو بتحديثه مع دعم المتغيرات المسماة ...

بناءً على جوهرك ، يبدو أنك توافق على @ Seven-stage-max. رقم؟

كانت الحجة أنه لا يمكنك تمرير المعرفات مثل mixin إلى وظيفة (لذلك يمكنك تمرير المعلمات إلى mixin الذي يعمل كمفوض lambda) ولا تنفيذ وظيفة دون تعيين ناتجها إلى متغير أو خاصية (مما يمنعك من استخدامها لـ إنشاء لامدا يمكنها إصدار CSS).

في حالتي ، أستخدم الوظيفة لالتفاف مجموعة قواعد منفصلة ثانية حول الأصل ، والتي تقوم بحقن "معلمات" لامدا (تشبه إلى حد بعيد كيفية عمل Definition.prototype.evalCall عند تمرير المعلمات إلى mixins ، في الواقع) ثم أعيد ذلك مجموعة قواعد ملفوفة نتيجة لذلك.
يمكن استدعاء مجموعة قواعد منفصلة ، بالطبع ، لإصدار CSS.

طبقة التغليف هذه تحل كلا المشكلتين.

تضمين التغريدة

أوه ... لن أكون متأكدًا جدًا من ذلك.

ما تظهره أن هناك مزيجًا لا يختلف عن هذا على سبيل المثال (هناك يمكنك فقط تبسيط حلقة أقل من خلال بعض الوظائف lambda ) ولكن لكي نكون منصفين ، فإن المكون الإضافي هو نوع من الزائدة هناك حيث يمكننا كتابة mixin باستخدام الوظيفة المتطابقة بدون أي مكون إضافي (إذا لم أكن مخطئًا ، فسيتم استخدام المكون الإضافي فقط لحظر متغيرات النطاق الخارجي).

لذا ، لا ، للإلغاء:

لذا ، لا ، في الوقت الحالي من المستحيل ببساطة تنفيذ كلٍّ من هذا عبر المكوِّن الإضافي.

تحتاج إلى إظهار each كدالة وليست مزيجًا ؛) (وإلا فهي نفس المناقشة كما هو الحال بعد https://github.com/less/less.js/issues/1943#issuecomment-72945408) .

كانت الحجة أنه لا يمكنك تمرير المعرفات مثل mixin إلى وظيفة

وما زلت لا تستطيع. DR ليس mixin! :) (لا يمكن أن تحتوي على معلمات على سبيل المثال). على سبيل المثال ، بصفتي مستخدمًا ، أريد أن يكون رمز lambda باسم @v و @i (أو أي شيء أحتاجه) لا أريد ذلك @item و @index bloatware! ؛)

كمستخدم ، أريد أن يكون رمز lambda الخاص بي مسمى @v و @i (أو أي شيء أحتاجه) لا أريد ذلك @item و @index bloatware! ؛)

هل فاتك الجزء الذي تكون فيه أسماء المعلمات قابلة للربط المخصص؟ لقد تم إصلاحها في المثال الخاص بي ، ولكن يمكنك _يمكنك_ تمريرها كوسيطة إضافية لأي mixin سيعالج مجموعة قواعد lambda. باستخدام جوهر بلدي كمثال:

.each(<strong i="12">@list</strong>, <strong i="13">@params</strong>, @ruleset) {
  <strong i="14">@length</strong> : length(@list);
  .iterate(1);
  .iterate(@index) when (<strong i="15">@index</strong> =< length) {
    <strong i="16">@item</strong> : extract(<strong i="17">@list</strong>, @index);
    <strong i="18">@out</strong>  : lambda(<strong i="19">@item</strong>, <strong i="20">@index</strong>, <strong i="21">@params</strong>, @ruleset);
    @out();
    .iterate(@index+1);
  }
})

.each(foo bar baz, v i, {
  value-@{i} : @v;
});

هذا ليس جافًا جدًا على الرغم من أنه يضع عبئًا على عمليات المزج التي تقدم دلالات رد الاتصال لتعيين هذا النوع من تكوين المعلمات. أفضل طريقة هي تقسيم دالة lambda نفسها إلى مكونين:

  1. a bind(@name-a, @name-b, ..., @ruleset) و
  2. أ pass(@bound-ruleset, @value-a, @value-b, ... )

عند هذه النقطة يكون للمتصل سيطرة كاملة على أسماء المعلمات:

.each(foo bar baz, bind(v, i, {
  value-@{i} : @v;
});

وداخليًا ، لا داعي للقلق بشأن mixin ، واتصل ببساطة بـ pass ثم قم بتقييم مجموعة القواعد المنفصلة المغلفة الناتجة.

.each(<strong i="36">@list</strong>, @ruleset) {
  <strong i="37">@length</strong> : length(@list);
  .iterate(1);
  .iterate(@index) when (<strong i="38">@index</strong> =< length) {
    <strong i="39">@item</strong> : extract(<strong i="40">@list</strong>, @index);
    <strong i="41">@out</strong>  : pass(<strong i="42">@ruleset</strong>, <strong i="43">@item</strong>, @index);
    @out();
    .iterate(@index+1);
  }
})

بالتأكيد؛ لا تزال ليست لامدا أصلية حقيقية ، لكنها تقترب بشكل قانوني ، أليس كذلك؟ ؛-)


بالطبع ، لا يزال كل هذا اختراقًا نأمل أن يتم استبداله بدعم اللغة الأصلية في وقت ما. ولكن حتى ذلك الحين ، يكون "polyfill" متوافقًا معنوية (وتقريباً نحويًا).

.each(foo bar baz, bind(v, i, { ...

في هذا السياق ، فإن المبالغة في استخدام الأقواس الثلاثة قادرة على القيام بأشياء سحرية أكثر:

.each(foo bar baz, { .function(<strong i="9">@v</strong>, <strong i="10">@i</strong>, @l) {
    threesome: <strong i="11">@v</strong> at <strong i="12">@i</strong> of ~"[" <strong i="13">@l</strong> ~"]";
}});

( ضمني ).

@ سبع مراحل كحد أقصى
هذا في الواقع ما كنت أستخدمه قبل وظائف البرنامج المساعد وكما لاحظت بالفعل في جوهرك: إنه يكسر التوقيعات المحملة بشكل زائد.

يمكنك أن تجعلها تعمل في الحالة البسيطة بتوقيع "التقاط كل شيء" استنادًا إلى معلمة الراحة (بحيث يكون للمكالمة .function دائمًا توقيع مطابق لمطابقة شيء ما ، بغض النظر عن المعلمات التي يمتلكها المستهلك زودت).
ومع ذلك ، يبدأ بعد ذلك في فعل أشياء غريبة حقًا ، _reaaaaa ------ lly_ عندما تبدأ في استخدام هياكل المكالمات المتداخلة مثل .each داخل .each . يؤدي استخدام مجموعة القواعد المنفصلة إلى تجنب هذه المشكلة مباشرةً.

على أي حال ، أعتقد أنه كان لي مجرد عيد الغطاس في إعداد هذا مع بعض بناء الجملة ألطف. سأقوم باختراقها أكثر قليلاً وأرى ما إذا كانت ستنجح. ^ _ ^

ومع ذلك ، فإنه يبدأ بعد ذلك في فعل أشياء غريبة حقًا ، عندما تبدأ في استخدام هياكل المكالمات المتداخلة مثل .each داخل .each. يؤدي استخدام مجموعة القواعد المنفصلة إلى تجنب هذه المشكلة مباشرةً.

نعم ، لهذا السبب ألتزم بخالي من DR .for بعد تقديم DRs ... ليس لديه مشاكل مع التعشيش ، ويسمح بالاسم المخصص @item والمشكلة الوحيدة هناك لمشاهدة أنه ليس كذلك تستخدم في mixin ليتم توسيعها إلى النطاق العالمي دون أن يحيط بـ {} .

وبالتالي؛ بعض الأخبار. لقد اكتشفت نوعًا ما كيفية الحصول على عملية تصغير للعمل:

.test {
  <strong i="6">@list</strong> : 1 2 3;
  <strong i="7">@init</strong> : 0;
  <strong i="8">@step</strong> : { <strong i="9">@return</strong> : @previous-item + @item; }

  .reduce(<strong i="10">@list</strong>, <strong i="11">@init</strong>, <strong i="12">@step</strong>, {
    value : @result;
  });
}
.test {
  value: 6;
}

(نعم ؛ لديّ وظيفة @plugin تسحب قيم الإرجاع القابلة للتخصيص من مجموعات القواعد التي تم تقييمها ...)

(نعم ، لديّ وظيفة plugin تسحب قيم الإرجاع القابلة للتخصيص من مجموعات القواعد التي تم تقييمها ...)

فقط لمشاركة فكرة. لدي بعض المكونات الإضافية قيد التطوير (ولكن ليس لدي وقت لإنهائه قريبًا ، أخشى) والذي يسمح لك باستخدام مزيج أقل أصلي كوظائف أصلية بالطريقة المتعارف عليها ، على سبيل المثال:

.function-foo(@x) {
    return: <strong i="11">@x</strong> * 5; 
}

usage {
    width: foo(100px); // -> 500px
}

من الواضح أن هذا يتطلب عددًا قليلاً من الاختراقات القذرة من داخل المكون الإضافي (تتعلق في الغالب بالحصول على سياق النطاق المناسب لما يسمى mixin داخل غلاف الوظائف الخاص به) نظرًا لأن هذا ليس شيئًا من المفترض أن تقوم به المكونات الإضافية على الإطلاق.

لكن النقطة المهمة هي: ربما يمكنك التفكير في شيء في هذا الاتجاه أيضًا؟ (للتخلص من التبعيات / الاختراقات العميقة جدًا للدكتور). كما أرى الآن الطريقة التي تستخدمها لصنع كل هذه الأشياء متعرجة تمامًا ، على سبيل المثال:

  • قم بعمل mixin لقبول DR كـ lambda.
  • إنشاء وظيفة (وظائف) مساعدة لاختراق DRs لجعلها تساعد في صنع ما يجب أن يقوم به mixin.
  • اخترع طريقة مخترقة لاستخدام هذا المزيج إذا لم تكن راضيًا عن أسماء المتغيرات الافتراضية (أو لأي سبب آخر ، فإن صياغة DRs-in لا تتناسب جيدًا)
  • إلخ.

لكن النقطة المهمة هي: ربما يمكنك التفكير في شيء في هذا الاتجاه أيضًا؟ (للتخلص من التبعيات / الاختراقات العميقة جدًا للدكتور).

إنها في الواقع نظيفة بشكل مدهش ، أكثر من ذلك الآن بعد أن طردت المزيد من الحِصاد. ؛-)

على أي حال ، ألا تعطيك الخلطات بعض المشاكل عند استخدامها كلامدا؟ أحد الأشياء التي يمكنني التفكير فيها هو أن استدعاء mixin الفردي قد يتطابق مع تعريفات متعددة ، وبالتالي يمكن أن ينتج عنه قيم إرجاع متعددة. في أي حالة؛ اي واحدة تاخذ

في أي حالة؛ اي واحدة تاخذ

تمامًا مثل أي مكان آخر: LDW .

آه ، ومرة ​​أخرى فقط في حالة: https://github.com/seven-phases-max/less-plugin-lists (أقوم بعمل مكياج في اللحظة الأخيرة قبل النشر). هذا الشيء متعامد تمامًا مع ما تصنعه (وظائف بدائية مقابل خوارزميات التكرار) ، ولكن سيكون من الغريب أن نرى كيف سيؤثر كلاهما على حالات الاستخدام المختلفة (عمليات البحث عن قيمة المفتاح على وجه الخصوص).

لدي بالفعل وظائف بدائية أيضًا ؛ لكل من القوائم والخرائط.
زيادات قائمتي هي إلى حد كبير ما كتبته أيضًا.

رأيت مرة أخرى أن شخصًا ما أراد نوعًا من each أصليًا لتمرير مجموعة من البيانات إلى mixin - # 2601.

أعتقد أنه لا يزال هناك مجال لإمكانية وجود شيء محلي.

اليوم ، قمت بعمل mixin بسيط لإخراج rems عندما يكون مدعومًا بواسطة متصفح:

.rem-size(<strong i="9">@property</strong>, @size) {
    @{property}: @size;
    @{property}: unit(<strong i="10">@size</strong> / 10, rem);
}

أضف في عناصري:

.widget {
  .rem-size(font-size, 14px);
  .rem-size(width, 50px);
  .rem-size(height, 50px);
  .rem-size(padding-top, 10px);
}

أدركت بعد لحظة أنه لسوء الحظ كانت قذرة بعض الشيء ، ولم يكن من السهل قراءتها. ما أردته كان شيئًا مثل:

.widget {
  .rem-size({
    font-size: 14px;
    width: 50px;
    height: 50px;
    padding-top: 10px;
  });
}

أشعر على الفور بمزيد من التوثيق الذاتي بالنسبة لي بقدر ما تقدر الممتلكات التي أقوم بتحويلها. بالطبع ... لا يوجد شيء مثل هذا في أقل. ما أردته هو شيء من شأنه أن يوسع كل أزواج الممتلكات / القيمة إلى مكالمات mixin لكل منها.

إذا نظرت إلى عدد حالات الاستخدام / المشكلات المتعلقة بهذا ، أعتقد أننا فقدنا القارب. يُعد توسيع القوائم إلى mixins ميزة مطلوبة كثيرًا ؛ كل ما في الأمر أن الناس يطلبونه بعدة طرق مختلفة.

ربما يمكن للمكونات الإضافية القيام بذلك ، لكنني لست متأكدًا الآن من أنها يجب أن تفعل ذلك بالضرورة. أعتقد أننا يمكن أن نتفق حتى الآن في هذا الموضوع على أن الوظيفة مطلوبة ، ونحن بحاجة فقط لاتخاذ قرار

  • [] إذا أردنا أن نضيف إلى جوهر ،
  • [] ما ينبغي أن يكون بناء الجملة.

هل هذا بيان عادل؟

@ ماثيو دين بيكسريم ؟ تبدو كتابة مكون إضافي للمعالج اللاحقة لحقن النسخ الاحتياطية لـ CSS المكتوبة بشكل طبيعي مثل font-size: 1rem; أكثر منطقية (إلى جانب البنية الاصطناعية ، lambda / كل / أيًا كان البناء قد يواجه أيضًا مشاكل مع خصائص مثل background: linear-gradient(135deg, red, blue) 1rem/2rem repeat-y fixed 3rem 4rem; ).

مجردة "مجموعة القواعد لمصفوفة أزواج الخاصية / القيمة" (والعودة) تبدو وظيفة التحويل / البناء جيدة ، ولكن بعد ذلك يتعلق الأمر بحالات الاستخدام لتشكيل بناء الجملة / السلوك الفعلي. لذا ، من الناحية الافتراضية ، لا يتم احتساب background: linear-gradient(135deg, red, blue) 1rem/2rem repeat-y fixed 3rem 4rem; مثل الأشياء ، ولكن هل عدّ أشياء مثل padding: 1 2 3 4 ، كيف سيبدو .rem-size داخليًا؟

@ سبع مراحل كحد أقصى:
مجردة "مجموعة القواعد لمصفوفة أزواج الممتلكات / القيمة" (والعودة) تبدو وظيفة التحويل / البناء جيدة

هيه. أنا في الواقع أستخدم مجموعة متصلة من الوظائف لبناء قواميس بهذه الطريقة.

يعمل بشكل رائع مع أشياء مثل تعيين سلسلة من رموز الخطوط مع نطاقات رموز الأحرف المتزايدة تلقائيًا ، حيث يمكنك إجراء تقييم لمجموعة القواعد (وأي مزيج بداخلها ؛ وبالتالي بناء الحلقات) قبل تحويل النتيجة التي تم تقييمها إلى قاموس مفتاح- أزواج القيمة.

على سبيل المثال

@map-icons     : map-build(@ruleset-icons);
@ruleset-icons : {
  <strong i="11">@chevrons</strong> : "chevron-up", "chevron-right", "chevron-down", "chevron-left";
  <strong i="12">@arrows</strong>   : "arrow-up"  , "arrow-right"  , "arrow-down"  , "arrow-left";

  .make-iconrange(<strong i="13">@chevrons</strong>, "e800");
  .make-iconrange(<strong i="14">@arrows</strong>  , "e810");
}

.make-iconrange(<strong i="15">@names</strong>, @code) {
  .iterate(hex2dec(@code), length(@names));
  .iterate(<strong i="16">@start</strong>, @index) when (<strong i="17">@index</strong> > 1) { .iterate(<strong i="18">@start</strong>, <strong i="19">@index</strong> - 1); }
  .iterate(<strong i="20">@start</strong>, @index) when (<strong i="21">@index</strong> > 0) {
    <strong i="22">@name</strong>   : e(extract(<strong i="23">@names</strong>, @index));
    @{name} : dec2hex(<strong i="24">@start</strong> + <strong i="25">@index</strong> - 1);
  }
}

// [ ... ]

.icon:before {
  <strong i="26">@code</strong>   : map-extract("chevron-up");
  content : "\@{code}";
}

(داخليًا ، يستخدم نوع عقدة جديد تمامًا لتخزين تعيين قيمة المفتاح ككائن حرفي ، مما يمنحك بحثًا ثابتًا في الوقت بدلاً من الاضطرار إلى استعراض القائمة بأكملها طوال الوقت لاستخراج قيمة لمفتاح معروف. السرعة -up مثير للغاية.)

تضمين التغريدة

هيه. أنا في الواقع أستخدم مجموعة متصلة من الوظائف لبناء قواميس بهذه الطريقة.


لاحظ أن كل هذا الرمز يستخدم فقط لمحاكاة التعدادات الشبيهة بـ C ، على سبيل المثال:

enum {
    a,
    b = 33,
    c,
    d = 42,
    e,
    etc
};


إذا كنت سأحاول استخلاص مثل هذا الرمز عبر وظائف البرنامج المساعد الخارجية ، فسأستخدم شيئًا مشابهًا لـ less-plugin-lists:at (بسلوك مختلف قليلاً) ، على سبيل المثال (عدم إظهار تحويل hex <-> dec):

<strong i="19">@icons</strong>:
    chevron-up #00e800, chevron-right, chevron-down, chevron-left,
    arrow-up   #00e800, arrow-right, arrow-down, arrow-left;

.icon(@name) {
    <strong i="20">@code</strong>: enum-value(chevron-down);
    content : "\@{code}";
}

.icon:before {
    .icon(chevron-down);
}


وإذا كنت تفضل أن تعمل هذه الوظيفة مع DR (بدلاً من القائمة البسيطة) فقد تكون مشابهة:

<strong i="27">@icons</strong>: {
    chevron-up: #00e800; chevron-right; chevron-down; chevron-left;
    arrow-up:   #00e800; arrow-right; arrow-down; arrow-left;
};

(ولكن نظرًا لأنه من غير القانوني تحديد خاصية / متغير بقيمة / oa بهذه الطريقة ، يصبح الأمر أكثر تعقيدًا ، على الرغم من أنه في حالة بسيطة ، يجب أن تساعد عملية خلط , / ; المصطنعة قليلاً ).(راجع للشغل ، لماذا تستخدم كل علامات الاقتباس هذه للقيم؟ CSS ليست JavaScript!: P المطلوب فقط " في المقتطف الخاص بك في content value.)


هذا لا يلغي فائدة الميزة لحالات الاستخدام الأخرى بالطبع.

بالنسبة لهذه الحالة بالذات ، تبدو كل تلك DRs ، وخرائط .map- mixins والحلقات المتطابقة هناك ، أكثر من اللازم بالنسبة لي.

صحيح. كان يجب أن أقول إنني _ حاليًا_ أستخدم وظيفة إضافية لبناء قواميس بهذه الطريقة. تتمثل خطتي في إعادة كتابة التحويل السداسي / dec للرموز إلى وظيفة مخصصة عند نقطة واحدة واستخراج الجزء الأخير من الفوضى باستخدام حلقة Less تلك الأصلية. لم يكن لدي الوقت للقيام بذلك حتى الآن.

شيء واحد بالرغم من ذلك:
حقيقة أنه يمكنك إنشاء خريطة / قاموس حقيقي_يعمل على "خريطة تجزئة" حرفيّة لكائن JS داخليًا لها بالفعل قيمة عملية كبيرة إذا كان عليك العمل مع مجموعات في مئات العناصر: -القائمة عبر اللغة الأصلية يصبح أقل بطيئًا جدًا في هذه الحالة.

(لم يكن المثال الخاص بي يمثل هذه الحقيقة تمامًا. في الحقيقة أنا أتعامل مع مجموعات من أكثر من 100 رمز في خطوط الرموز المصممة خصيصًا وسرعان ما اكتشفت أن حلقة Less loop لعمليات البحث لا تقطعها.)

@ Seven-stage-max أشعر وكأنك قد توقفت عن حالة الاستخدام / بناء الجملة ، عندما كان كل ما أقوله هو أنني أردت طريقة نظيفة لكتابة قائمة يمكنني تكرارها.

كانت نقطتي الأساسية هي: أن الكثير من الأشخاص يصادفون سيناريوهات أقل حيث هم
أ) لديك قائمة ،
ب) تريد تنفيذ mixin لكل عضو في القائمة.

ما إذا كان السيناريو الخاص بي يمكن / ينبغي القيام به مع معالج ما بعد هو إلى حد ما غير ذي صلة ومسألة رأي.

(بالرغم من وجود رأيين حول ذلك:
1) أقل يوفر CSS مترجم إلى PostCSS والذي يجب تحويله بعد ذلك مرة أخرى إلى AST ، لذا فإن المعالجة القائمة على PostCSS هي نمط غير فعال إلى حد ما إذا كان mixin يحلها ،
2) حتى لو تم حلها ، فإنها تضيف عبئًا تقنيًا على مكدس المعالجة الخاص بي. لكن ، مرة أخرى ، لست مهتمًا حقًا بمزايا PostCSS بقدر ما يتعلق بهذا الموضوع.)

بينما تسأل المشكلة في الأعلى عن lambdas على وجه التحديد ، كانت معظم المناقشة تدور حول بناء جملة من النوع "كل" ، لأن REASONrjgotten الأصلي أراد lambdas أو "مزيج معلمات كمجموعات قواعد منفصلة لتكوين lambdas في المثال الأولي: .forEach .

لذلك كنت ببساطة أعيد النظر في هذا: هذا هو السؤال عن المواطن الأصلي each() . وطرح السؤال مرة أخرى حول ما هو إجماعنا بالضبط ، ليس حالة استخدامي صالحة.

لتوضيح هذه الأسئلة بشكل أكثر وضوحًا:
1) هل هناك حاجة لإرسال قوائم إلى mixins التي يمكن أن تعمل على كل عضو في القائمة؟ (أعتقد ذلك ، لأنه جزء من وثائقنا المعتادة).
2) هل هناك حاجة كافية لأن الميزة الأصلية لا تزال قيد الاعتبار؟ بدلاً من اللجوء إلى الاختراقات .-() when ؟
3) إذا كانت هناك حاجة ، فماذا قد يكون بناء الجملة؟

أشعر بالفضول فقط أين يقف هذا وما هي الآراء المطروحة على الطاولة.

@ ماثيو دين

ب) لذلك كنت أعيد النظر في هذا ببساطة: هذا هو السؤال عن مواطن من السكان الأصليين each() .

لكنك قمت بذلك بالفعل على https://github.com/less/less.js/issues/2270#issuecomment -72969605.

إذا حاولت استخدام قائمة وحلقة لـ rem / px polyfill ، فستنتهي برمز مثل هذا (لا يهم تركيب الحلقة هنا ، فالمشكلة تكمن في الحلقة الداخلية).

كتابة ملحق ما بعد المعالج لإدخال العناصر الاحتياطية لـ CSS المكتوبة بشكل طبيعي مثل حجم الخط: 1rem ؛ يبدو أكثر منطقية


على سبيل المثال ، يمكن كتابة "rem polyfill" (ومن الأفضل كتابته) كـ "زائر ما بعد التقييم" يعمل مباشرة مع Less AST (وبالتالي لا علاقة له بـ PostCSS أو أشياء خارجية أخرى على الإطلاق).


بغض النظر عن ملاحظة rem polyfill هذه ، لا أرى أي خطأ في each أصلي (العمل مع كل من القوائم العادية ومع القواعد كمصفوفات مفتاح / قيمة). على الرغم من ملاحظة أنه كلما زاد rjgotten من مكتبته ، كلما تحرك في اتجاه مختلف: لا توجد حلقات وبحث مباشر في القاموس (والذي لا يمكن لـ Less نفسه استخدامه مع قواعده إلا إذا كانت تحتوي على متغيرات _only_). لذلك بدأنا في الحصول على ميزتين متعامدتين تمامًا هنا.
(في الواقع ، حتى ثلاثة: lambda (من الواضح أنه ليس بالضرورة مرتبطًا بالحلقات) ، و each و key/value الهياكل كقاموس (للبحث المباشر) أو كمصفوفة (للحلقات)).

لكنك فعلت هذا بالفعل

بالتأكيد ، حسنًا ، ربما كان تعليقي طويلًا جدًا وكان يجب أن أقول للتو ، "لقد ظهر هذا في ذهني مرة أخرى اليوم ؛ أين وصلنا مع هذا؟" بقدر ما أستطيع أن أقول ، لم نقترب من أي توافق في الآراء. آسف إذا كان هذا الخلط.

جزء من المناقشة ذات الصلة بهذا التعليق هو مسألة اجتياز المحددات بالإشارة. @ Seven-stage-max الذي ذكرته بالفعل في # 1848 أن مناقشة الإشارة إلى ${} كانت ذات صلة بهذا الموضوع.

لذلك ، يمكن أن يكون جيدًا جدًا:

each(a b c; ${.mixin} );

أو

each(a b c; ${#namespace.mixin} );

ربما يجب تنفيذ # 1848 & # 2433 أولاً؟

نعم ، أفترض أن هذه الأشياء ستكون مفيدة معًا (وبالتالي يجب أن تأخذ بعضها البعض في الاعتبار عند تصميمها) ، لكن لا يوجد تبعية مباشرة. على سبيل المثال ، يعتبر each(a b c; ${.mixin} ); رائعًا (للأشياء المعقدة) ولكنه يوفر آلية لسهولة استخدام هيكل الحلقة المضمنة .

تقصد ، فقط استخدم لامدا بدلا من ذلك؟

أووبس. إنه مجرد خطأ مطبعي. أعني "لكنها لا توفر آلية لسهولة استخدام جسم حلقة مضمنة".
بمعنى آخر ، من الناحية المثالية ، يجب أن تكون طريقة لكتابة جميع الكودات الضرورية داخل each نفسها ، كما في:

each(<strong i="8">@list</strong>, (@value) {
    box-shadow+: <strong i="9">@value</strong> black;
});

أو (مجرد محاولة الخروج من بناء جملة يشبه JS):

each(@list): (@value) {
    box-shadow+: <strong i="13">@value</strong> black;
}
// ^ this one won't be compatible with external DR or mixins of course :(

أو هكذا...

نعم ، إذا سمحنا بالخلطات المجهولة ، فأعتقد أنها ستكون قابلة للتبديل مع كل ما نستخدمه كمرجع mixin. لذا ، أجل ، أعتقد أن مثالك الأول شرعي ومتوافق.

مثال مهمتك مثير للاهتمام. تعجبني فكرة الشيء الأنظف.

لقد تساءلت أيضًا عما إذا كانت هناك طريقة لقلبها ، للتحايل على مشكلة مرجع mixin. وهذا يعني ، بعض الطرق لتمرير القائمة إلى mixin ، بدلاً من تمرير mixin والقائمة إلى كل منهما ، مثل:

.mixin[@list];  // Different syntax to evaluate each member of the list?
// or
.mixin each @list;   //better

ثم لا يزال الأمر أكثر نظافة حتى مع لامدا:

(@value) {
    box-shadow+: <strong i="11">@value</strong> black;
} each @list;

// or maybe better as:

(<strong i="12">@index</strong>, @value) each <strong i="13">@list</strong> {
    box-shadow+: <strong i="14">@value</strong> black;
} 

ويحتمل أن:

.mixin each <strong i="18">@list</strong> when (length(@list) = 1);

ما رأيك في ذلك؟

في كلتا الحالتين ، أعتقد أنك قد أدركت بشكل صحيح أن اقتراحي الأولي هو JavaScript-y أكثر من اللازم. أحب فكرة "التوسع الإعلاني" هذه.

على الرغم من أن هذا ربما يحتاج إلى تعديل بسيط في بناء الجملة ، للسماح بتمرير القوائم كقوائم بدلاً من المتغيرات:

<strong i="6">@list</strong>: a b c;
.mixin each (@list);
.mixin each (d e f);

//with mixin definition
.mixin(@letter) {
  property: @letter;
}

في كلتا الحالتين ، أعتقد أنك قد أدركت بشكل صحيح أن اقتراحي الأولي هو JavaScript-y أكثر من اللازم.

إنها ليست في الواقع "JavaScript-y" ، فمن المؤكد أنها مجرد استمرار طبيعي لاستدعاء mixin باستخدام بنية وسيطة DR التي لدينا بالفعل: .mixin(arg1, {/* stuff */}); ، أي أنها مجرد أقواس وأقواس من كيانات لغة مماثلة تتشكل معًا في بطريقة مماثلة لبناء مماثل :)


الحديث عن بديل. بناء الجملة ، في الواقع ، ذكّرتني الأمثلة الأخيرة بالفعل بفكرة واحدة أحصل عليها دائمًا عند التعامل مع القوائم / الحلقات المعقدة والأشياء ذات الصلة. "سيكون من الأسهل والأكثر نظافة إذا تم إطلاق الدوال والعمليات الحسابية بطريقة" vectorized "". أي بدلاً من الكتابة منتفخة:

<strong i="11">@x</strong>: 3rem;
padding: 1 * <strong i="12">@x</strong> 2 * <strong i="13">@x</strong> 3 * <strong i="14">@x</strong> 4 * @x;

يمكن للمرء أن يفعل فقط (النحو الزائف):

padding: (1 2 3 4) * @x;

وهكذا (بما في ذلك vector op vector -> vector الأشياء).

بالطريقة نفسها ، يمكن أن يكون للوظائف (بدلاً من محاولة معالجة قوائم القوائم من تلقاء نفسها عند عدم الضرورة) وضع اتصال "متجه" أيضًا ، على سبيل المثال:

@base-colors: red green blue black;
@light-colors: <some vector call mark>:::lighten(@base-colors, 15%); // same unknown pseudo syntax

@another-list: 10 20 30 40;
@more-light-colors: <some vector call mark>:::lighten(@base-colors, @another-list * 1%);

الآن ، في الواقع ، عندما ذكرت ذلك ، أدركت أن نفس الشيء (لا توجد فكرة عن بناء الجملة حتى الآن) عند تطبيقه على mixins ، ليس أيضًا سوى بناء each ...
من الغريب أنني أفترض أنه سيكون من السهل نسبيًا تنفيذه ، لكن بناء الجملة نفسه قد يمثل مشكلة في الصياغة (بصراحة لا يمكنني ابتكار أي شيء مفيد حتى الآن). بجانب تحديد أن علامة vector/each نفسها ، يجب أن توفر أيضًا التحكم في ما يجب أن يكون "متجهًا" لاستدعاء mixin / function من أجل arg و arg_s .

على سبيل المثال ، بالنظر إلى .mixin(a1, a2, ..., an) {...} (أو دالة ذات وسائط متعددة) ، هناك العديد من المتغيرات "لكل منها" (بافتراض أننا لا نريد وضع أي قيود على mixin نفسه وكود ثابت للبناء نفسه لـ حالات خاصة فقط):

  1. استدعاء .mixin لكل عنصر a1 (يتم تمرير a2 كما هو)
  2. استدعاء .mixin لكل عنصر a2 (يتم تمرير a1 كما هو)
  3. استدعاء .mixin لكل عنصر a1 و a2 (كما في .mixin(a1[i], a2[i] ))
    إلخ.

بمعنى آخر ، (من أجل البساطة في أخذ الخلطات المحددة صراحةً فقط ، دون مراعاة جسم التكرار "الداخلي" حتى الآن) ، مع بناء جملة زائف يصبح شيئًا مثل:

each(<multiple args>) mixin(<normal-arg or a place-holder for one of "each" arg items>)...

// i.e.

<strong i="48">@a</strong>: 1 2 3 4;
<strong i="49">@b</strong>: 42;
<strong i="50">@c</strong>: 5 6 7 8;

each(@a) mixin(<each-arg-1-place-holder>, <strong i="51">@b</strong>, ...)
each(@a) mixin(<strong i="52">@b</strong>, <each-arg-1-place-holder>, ...)
each(@a) mixin(<each-arg-1-place-holder>, <each-arg-1-place-holder>, ...)
each(<strong i="53">@a</strong>, @c) mixin(<each-arg-1-place-holder>, <each-arg-2-place-holder>, ...)
each(<strong i="54">@a</strong>, @c) mixin(<each-arg-2-place-holder>, <each-arg-1-place-holder>, ...)
// etc. etc.

بالإضافة إلى أنه يجب أن يكون هناك حوامل نائبة للفهرس الحالي بالطبع (للتعامل مع الأشياء الشرطية بالداخل). إلخ.


حسنًا ، أعتقد أنك ترى الفكرة بالفعل.
(أدرك أن كل هذا قد يبدو معقدًا للغاية لأنني أحاول تغطية القصة بأكملها مرة واحدة ، ولكن بشكل عام أعتقد أن هذا يمكن أن يتغلب على أي نظام تكرار آخر يمكن أن يكون ، بشرط أن يتمكن المرء من اختراع بناء جملة نظيف مع "أنت لا تفعل" لا أحتاج إلى تحديد الأشياء التي لا تستخدمها هناك "حيثما أمكن ذلك. حسنًا ، سأستمر في التفكير إذا كان بإمكاني (إعادة) تقديم هذا بشكل أفضل).

على سبيل المثال ، عند إعطاء a. mixin (a1 ، a2 ، ... ، a) {...} (أو دالة ذات وسيطات متعددة) ، هناك العديد من المتغيرات "لكل منها" (بافتراض أننا لا نريد وضع أي قيود على الخلط نفسه وترميز البناء نفسه لحالات معينة فقط):

أعتقد أنه من أجل البساطة ، نود فقط دعم تمرير قائمة واحدة إلى مزيج واحد في وقت واحد. أعتقد أنني ضمنت أنه إذا كانت قائمتك عبارة عن قائمة قوائم ، فسيتم تمرير كل عضو في القائمة الداخلية كحجج فردية. على الرغم من ذلك ، من الناحية النظرية ، يمكننا القيام بالأمرين معًا ، من خلال مطابقة mixin arity.

.mixin(@list) { }
.mixin(@a; @b; @c) { }

<strong i="8">@nested</strong>: 1 2 3, 4 5 6, 7 8 9;
.mixin each (@nested);   // or each(@nested)::mixin();  or whatever

إذا قمت بتحديد mixin الذي يتطابق مع معلمة واحدة ، فإنه يستدعي أي mixin يطابق معلمة واحدة ويمرر القائمة. إذا كان لديك mixin مطابق مع العدد الصحيح من الوسائط للقائمة الداخلية ، فقد يتطابق مع هذا mixin.

لا أعرف ما إذا كان لدينا هذا كحارس (ألا تعتقد ذلك؟) ، ولكن يمكنك القيام بما يلي:

.mixin(@list) when (islist(@list)) { }

... في حال احتجت إلى فصل حالات mixin التي يتم استدعاؤها للقائمة مقابل أعضاء القائمة المدعوين.

أيضًا ، أعتقد أنه في حالة التكرار ، يجب أن يظهر index كمتغير سحري (مثلarguments) ، بدلاً من الحاجة إلى تعريفه في تعريف mixin نفسه (وهو أمر ممل). بحيث يمكنك القيام بما يلي:

.mixin(@x) when (<strong i="18">@index</strong> = 0) { 
  // add stuff for the first call
}

أنا أحب مادة المتجه الخاصة بك ، ولكن من المحتمل أن يكون بناء الجملة رقيقًا جدًا / غامضًا بعض الشيء. (الأقواس المستخدمة بالفعل مع بيان الرياضيات العادي / mixin / الوظيفة / إلخ) أحب أيضًا فكرة بناء جملة "التوجيه" أو "الإسناد" من كل منهما إلى mixin. أنا أيضًا حاولت التوصل إلى شيء ما ، أو التفكير في أي شيء CSS-y ولكن بدلاً من ذلك ذهبت بشيء أقل.

عمل جيد!

قررت أن أحاول معالجة هذا باستخدام البنية والبنى الموجودة: أي تمرير قائمة ومجموعة قواعد إلى وظيفة وتحويل مجموعة القواعد بناءً على أعضاء القائمة.

تحقق من العلاقات العامة ذات الصلة.

@ Matthew-dean Mm ... إليك تنفيذ مكافئ تقريبًا (لم يتم تحسينه ، بدون معالجة أي خطأ) _ بدون _ يتطلب أي تغييرات في النواة. الاختلاف الوحيد هو أنه بدلاً من each ، فإنه يوفر .each .

آمل أن تدرك أنه نظرًا لأن تنفيذك يتطلب تغييرين أساسيين رئيسيين ، فلن يتم قبوله في أي وقت قريب. أولاً ، يجب أن نتحدث عن الأمر حتى الموت. (كمية الأشياء التي يجب تحليلها وكمية الاختبارات المراد كتابتها مخيفة بعض الشيء).

ملاحظة: في كلتا الحالتين: +1:

حسنا جاءت الإضافات أولا. لقد بدأت في محاولة القيام بشيء ما ، أي شيء مفيد من حيث استخدامه مع إطار عمل ، والقدرة فقط على إرجاع قيمة الخاصية تكون ذات قيمة محدودة بحيث لا تستحق ذلك العناء.

ولكن ، مثل المزيجات ، يمكن للوظائف أن تتوسع في مكانها عند أي عمق عقدة ، وهذا يفتح كل شيء. لا تزال الوظائف ترجع حقًا عقدة واحدة فقط ، كما فعلت من قبل ، ولكن القيد على نوع العقدة يتم رفعه ببساطة.

كان تنفيذ كل () في الأساس فكرة لاحقة بعد ذلك. أدركت أنه بمجرد أن تتمكن من تحديد وظيفة للتوسع في أي نوع عقدة ، ويمكن أن تتلقى هذه الوظيفة أي نوع آخر من العقدة ، ثم يصبح الأمر برمته واضحًا جدًا. أردت أيضًا اختبار واجهة برمجة التطبيقات الحالية.

أعلم أنه تغيير كبير. كل () لا أهتم كثيرًا إذا كانت جوهرها ، بخلاف الاختراقات الحلقية ، تميل إلى أن تكون شائعة إلى حد ما. ولكن يمكن أن يكون أيضًا الدليل المعروض على مفهومplugin. (ربما يكون أحد المكونات الإضافية "الأساسية" القليلة). لكلتا الطريقتين بعض الصلاحية.

بقدر ما تتغير الوظيفة نفسها ، إذا كان بإمكان هؤلاء المضي قدمًا ، أود إجراء المزيد من العلاقات العامة التي تبسط واجهة برمجة التطبيقات (API) إلى حد كبير ، ومن ثم سأكون سعيدًا بتولي مسؤولية التوثيق الشامل لواجهة برمجة التطبيقات وتحديث المستندات الأقل. بعد العمل مع عقد الشجرة ، أعتقد أنها معقدة للغاية ومربكة للغاية بحيث لا تستحق التوثيق. لكن لدي أفكار حول كيفية إصلاح ذلك.

ولكن ، مثل المزيجات ، يمكن للوظائف أن تتوسع في مكانها عند أي عمق عقدة ، وهذا يفتح كل شيء. لا تزال الوظائف ترجع حقًا عقدة واحدة فقط ، كما فعلت من قبل ، ولكن القيد على نوع العقدة يتم رفعه ببساطة.

كان تنفيذ كل () في الأساس فكرة لاحقة بعد ذلك.

: +1:

each() هو عرض _ جميل جدًا للتطبيق الموسع للوظائف في القواعد ، لكن القواعد الموسعة هي الميزة القاتلة الحقيقية.

rjgotten الحق؟ كنت ألعب بفعل أشياء رائعة مثل إعادة مجموعة قواعد منفصلة بوظيفة إلى متغير ثم استدعائها. لذلك من المحتمل أن تقوم بتحويلات فريدة على DRs (وهو نوع من ما تفعله كل ()) ، ولديك أساسًا قوة على مستوى PostCSS ، باستثناء أقل المكونات الإضافية تلعب بشكل أفضل مع الآخرين حسب التصميم ، ويسهل تثبيتها (لأنك لا يتعين عليك تثبيتها على الإطلاق قبل استدعاء المترجم الأقل).

أود حقًا أن تتم مراجعة plugin PR من قبل الجميع ، بحيث لا تحتاج إلى البقاء إلى الأبد.

أود حقًا أن تتم مراجعة @plugin PR من قبل الجميع ،

هل تقصد # 2785؟
إذا كان الأمر كذلك ، فإن ميزة "Root Functions" (أو "Allow Non-Value Functions" مثل "Root" هي ميزة مربكة) لأنها ليست محدودة (أو يجب أن تقتصر) على المكونات الإضافية من أي تنسيق. ألقيت نظرة سريعة على الكود ولم أجد أي خطأ. إنها مجرد معالجة للخطأ يجب أن تكون مصقولة (حسنًا ، أعتقد أنه يمكنني إجراء علاقات عامة للفرع لإجراء تغييرات مقترحة)).

هل يمكن لدالة إرجاع مجموعة من القواعد؟ (من خلال إنشاء مجموعة قواعد & أو محاكاة استدعاء DR لإرجاع مثل هذه المصفوفة ، يبدو أنها محدودة. ماذا لو أردت إرجاع قائمة من التعريفات المتغيرة؟ :) على الرغم من أنني أفترض أن هذا يمكن تحسينه لاحقًا.

نعم ، # 2785. السبب في @plugin هو الموضوع لأنني لم أفكر في ما يمكن أن يعنيه للوظائف الأساسية. لذلك ، في ذلك الوقت كنت أفكر للتو في الوظائف المخصصة.

كان 2786 مبنيًا على # 2785 ، وإلا فلن تتمكن من القيام بوظيفة جذر مثل each() . لم أكن أعرف طريقة git أفضل للقيام بذلك ، ولكن بشكل أساسي إذا كان # 2785 موجودًا ، فسيبدو # 2786 أصغر كثيرًا. إنه حقًا مجرد هذا الالتزام: https://github.com/less/less.js/commit/f52b0736015d69f01e9be3257b039f2f332a613f

@ Seven-stage-max نتمنى أن تكون قد لاحظت أنني قمت بعمل حالة اختبارية لسيناريو "الرياضيات المتجهية" ، كهدية لك ، لول. يسعدني القيام بحالات اختبار أخرى أو تنظيف الأخطاء لـ # 2785 ، لأنني متحمس لهذه الحالة.

بالمناسبة ، مجرد إلقاء نظرة على التنفيذ الخاص بك. هذا محرج لأنني لم أنظر إلى ذلك سابقًا ، أو ربما وعدت بأن التطبيقات متشابهة جدًا؟ يعجبني أنك استخدمت value بدلاً من item . ربما هذا أفضل. لم يعجبني حقًا فاران يبدأان بـ "أنا". التنفيذ رائع ، لكنه لا يزال يوفر الكثير من التعليمات البرمجية الزائدة بدون وظائف الجذر. خلاف ذلك ، فإن رمزنا قريب جدًا.

أحد الأسباب التي دفعتني إلى البدء في البحث عن وظائف بدلاً من مزيج مخصص هو أنه ، حقًا ، من المنطقي فقط وجود وظيفة أو mixin each() . مع الوظائف ، هذا صحيح بالتصميم ، لذا فهو تطابق منطقي. ونظرًا لأن mixin الخاص بك يستدعي دالة تنقل قيمة إلى متغير إلى تقييم مجموعة القواعد ، فإن كل هذه الخطوات هي ببساطة "نقل" نتيجة الدالة إلى جذر مجموعة القواعد. والنتيجة المقصودة هي أن يتم تقييم وظيفتك من الجذر.

أو ربما يكون واعدًا بأن التطبيقات متشابهة جدًا؟

هذا فقط لأنني سرقت الرمز منك حرفيًا :) (لقد راجعت للتو بعض الأشياء بحيث تحتفظ القواعد التي تم إرجاعها برؤية تشبه DR).

يعجبني أنك استخدمت القيمة بدلاً من العنصر. ربما هذا أفضل.

في الإصدار النهائي ، سيكون أيضًا [value index] بدلاً من [index value] بالطبع.


بشكل عام ، يعد تطبيقي مجرد حل تجريبي لمشكلة "عدم وجود وظائف جذر" (بالإضافة إلى عدم تمرير قيمة DR مباشرة) ، لا شيء أكثر من ذلك. أخيرًا (في سياق هذا الموضوع) فإنه يكشف فقط عن السابق :

ولا يمكنك استدعاء دالة بدون إسناد نتيجتها إلى شيء ما ...

يمكن خداعها بعد كل شيء (على الرغم من أن القيود الأخرى لا تزال سارية بحيث لم يتم _that_ each ، لكنها في الواقع قريبة جدًا).


ولكن بمجرد أن يتسع نطاقه أكثر من هذا الخيط المحدد ، فلا شك في أن "السماح بالوظائف غير ذات القيمة" هو السبيل للذهاب. بالإضافة إلى "تحسين صيغة الحجج الوظيفية" (لأكون صادقًا ، لا أهتم بهذه ; هناك لأنني على أي حال سألتزم بـ each(a b c, value index, {...}); ، ولكن يجب أن تكون DRs مقبولة بدلاً من بالطبع ليعمل كل شيء).

أوه هاها أعتقد أنك كنت تقول أنك نفذتها في وقت ما من قبل.

نعم ، توفر الفاصلة المنقوطة نفس الاختيارية مثل ما يتم استخدامه لـ Mixins ، لذلك لا يوجد عبء على الدعم. في الواقع ، لقد استبدلت كود وسيطات الوظيفة بنسخة معدلة من كود وسيطات mixin ، على الرغم من أنني أعتقد أنني أضفت "مهمة".

المتابعة فوق أشياء " each() عبر البرنامج المساعد". لقد توصلت إلى طريقة تنفيذ جديدة (قائمة على المكون الإضافي) يمكن تطبيقها فعليًا على بناء جملة _any_ for/for-each/each يمكنها تمرير المحلل اللغوي.
على وجه الخصوص ، من خلال إساءة استخدام # 2824 ، فإن البنية التالية ممكنة حاليًا (انظر النموذج الأولي السريع ):

<strong i="10">@list</strong>: a b c, e f g;

usage {
    .for-each(<strong i="11">@x</strong> in @list) {
        .for-each(<strong i="12">@y</strong> in @x) { 
            r: <strong i="13">@y</strong> of ~"[@{x}]";
        }
    }
}

بنفس الطريقة ، يمكن استخدام أي صيغة مناسبة أخرى بدلاً من ذلك ، على سبيل المثال:

.for(<strong i="17">@value</strong>, in, @list)  {...} // mixin def. not abusing #2824
.for(<strong i="18">@i</strong>: 0, <strong i="19">@n</strong>: 6)       {...}
.for(any thing)          {...} // not abusing #2824 as long as no @
<strong i="20">@for</strong> (any thing)         {...}
.for(<strong i="21">@value</strong> in <strong i="22">@list</strong>,    {...});
:for(i 1:6)              {...}
:for(value in list)      {...}
 for [value] in [list]   {...}
 for {<strong i="23">@value</strong>: in @list; -{...}}
// etc. and so on

(قد يختلف تعقيد رمز التقييم كثيرًا).

@ سبع مراحل كحد أقصى
هذا أجزاء متساوية رائع ومرعب ...

rjgotten @ سبع مراحل ماكس متفق عليه. على الرغم من أنه ربما 60٪ مرعب.

وجدت هذا الخيط الرائع عندما وجدت نفسي بطريقة ما أشعر وكأنني بحاجة إلى إغلاق في CSS 😄

لدي الآن هذا المزيج لإنشاء إصدارات متجاوبة مسبوقة لأدوات مساعدة مختلفة:

.responsive(@ruleset) {
    & { <strong i="7">@prefix</strong>: ~""; @ruleset(); }
    <strong i="8">@media</strong> (min-width: @screen-sm) { <strong i="9">@prefix</strong>: ~"sm-"; @ruleset(); }
    <strong i="10">@media</strong> (min-width: @screen-md) { <strong i="11">@prefix</strong>: ~"md-"; @ruleset(); }
    <strong i="12">@media</strong> (min-width: @screen-lg) { <strong i="13">@prefix</strong>: ~"lg-"; @ruleset(); }
    <strong i="14">@media</strong> (min-width: @screen-xl) { <strong i="15">@prefix</strong>: ~"xl-"; @ruleset(); }
}

تستخدم مثل:

.responsive({
    .@{prefix}block { display: block;}
    .@{prefix}inline-block { display: inline-block;}
    .@{prefix}hidden { display: none;}
});

يعمل بشكل جيد ، لكني أتمنى أن يكون المتغير @prefix بطريقة ما معلمة لمجموعة القواعد ، بدلاً من الاضطرار إلى تحديده على الفور قبل استدعاء مجموعة القواعد وجعل مجموعة القواعد على علم بالاسم.

أحب أن أتمكن من إعادة كتابة كل ما سبق شيئًا مثل هذا:

.responsive(@ruleset) {
    & { @ruleset(~""); }
    <strong i="24">@media</strong> (min-width: @screen-sm) { @ruleset(~"sm-"); }
    <strong i="25">@media</strong> (min-width: @screen-md) { @ruleset(~"md-"); }
    <strong i="26">@media</strong> (min-width: @screen-lg) { @ruleset(~"lg-"); }
    <strong i="27">@media</strong> (min-width: @screen-xl) { @ruleset(~"xl-"); }
}

.responsive((@prefix) {
    .@{prefix}block { display: block;}
    .@{prefix}inline-block { display: inline-block;}
    .@{prefix}hidden { display: none;}
});

هل هذا هو الشيء الذي يمكن أن تجعله الأفكار المقدمة في هذا الموضوع ممكنة؟

بالمناسبة. لدي فكرة من حين لآخر حول احتمال دقة تركيب الغموض (للإجابة https://github.com/less/less.js/issues/2270#issuecomment-61634539). يمكننا فقط وضع بعض الرموز مباشرة قبل قائمة المعلمات ، على سبيل المثال:

<strong i="6">@var</strong>: @(parameters...) {...body...};
.call(@(parameters...) {...body...});

(كنت أكتب مؤخرًا بعض رموز Matlab وأدركت - boom - أنهم يستخدمون ذلك فقط لوظائف مجهولة). من الواضح أنه لا يجب أن يكون الرمز @ (يمكن أن يكون . ، ? وما إلى ذلك ، ولكن ليس العمليات الحسابية أو العلائقية) ، ومن ثم فهو *( فقط => بناء الجملة).

راجع للشغل ، adamwathan أنت تعلم أن شفرتك الحالية ستفشل إذا كان لديك أحيانًا متغير @prefix عالمي ، أليس كذلك؟

يا @ سبع مراحل كحد أقصى!

راجع للشغل ، adamwathan أنت تعلم أن شفرتك الحالية ستفشل إذا كان لديك أحيانًا متغير @prefix عالمي ، أليس كذلك؟

تمامًا ، هذا سبب كبير يجعلني أتمنى أن أتمكن من تحديد مجموعة قواعد منفصلة تقبل المعلمات ، لذلك يمكن تحديد نطاق أي بيانات تحتاجها بشكل صحيح.

هل يمكنك التفكير في طريقة بديلة للكتابة واستخدام هذا المزيج المولد الذي لا يحتوي على هذه المشكلة؟

.responsive(@ruleset) {
    & { <strong i="12">@prefix</strong>: ; @ruleset(); }
    <strong i="13">@media</strong> (min-width: @screen-sm) { <strong i="14">@prefix</strong>: sm-; @ruleset(); }
    <strong i="15">@media</strong> (min-width: @screen-md) { <strong i="16">@prefix</strong>: md-; @ruleset(); }
    <strong i="17">@media</strong> (min-width: @screen-lg) { <strong i="18">@prefix</strong>: lg-; @ruleset(); }
    <strong i="19">@media</strong> (min-width: @screen-xl) { <strong i="20">@prefix</strong>: xl-; @ruleset(); }
}

.responsive({
    .@{prefix}block { display: block;}
});

طريقة بديلة

يعتمد ذلك على كيفية استخدامك لتلك "المعلمة". على سبيل المثال ، في حالة بسيطة مثل أعلاه ، لا تحتاج إلى أي معلمة على الإطلاق [1] :

.responsive(@ruleset) {
    @ruleset();
    <strong i="10">@media</strong> (min-width: sm) {sm-{@ruleset();}}
    <strong i="11">@media</strong> (min-width: md) {md-{@ruleset();}}
}

.responsive({
    &block {display: block}
});

سيكون أقصى الطرف الآخر:
طريقة [2] "الأقواس الثلاثية" ، على سبيل المثال:

.responsive(@rules) {
    & {@rules(); .-(~'')}
    <strong i="18">@media</strong> (min-width: sm) {@rules(); .-(sm-)}
    <strong i="19">@media</strong> (min-width: md) {@rules(); .-(md-)}
}

.responsive({.-(@prefix) {
    @{prefix}block {display: block}
}});

و "up-side-down" ، مثل [3] :

.apply-responsive() {
    .responsive(~'');
    <strong i="25">@media</strong> (min-width: sm) {.responsive(sm-)}
    <strong i="26">@media</strong> (min-width: md) {.responsive(md-)}
} .responsive(...) {} .apply-responsive();

.responsive(@prefix) {
    @{prefix}block {display: block}
}

والكثير من الاختلافات بين هذه الثلاثة أعلاه اعتمادًا على الاستخدام الفعلي / حدود الإسهاب الضمني مقابل الاستخدام المقبولة (على سبيل المثال ، بالنسبة لإسهاب الاستخدام ، تفوز الطريقة [3] حتى على DRs المعلمية ، ولكنها تقتصر على العالمية تعاريف .resposive فقط ، لذلك يجب نقل أي أنماط متداخلة هناك).

@ سبع مراحل ماكس كل هذا مفيد للغاية ، شكرا لك! أنت محق ، الخيار الأول يعمل بشكل مثالي في حالتي ، لم أفكر في استخدام & للتعامل مع هذا. شكرا!

من الواضح أنه ليس من الضروري أن يكون الرمز @ (يمكن أن يكون. ،؟ وما إلى ذلك ، ولكن ليس العمليات الحسابية أو العلائقية) ، وبعد ذلك يكون فقط * ("الرمز المميز" الذي يحدد بشكل لا لبس فيه بداية البناء بأكمله (أعتقد سيكون أسهل بكثير وبالمقارنة مع المحلل اللغوي والعينين

@( هو مخرج سريع إلى حد ما للمحلل اللغوي ، لأنه يحتاج فقط إلى حرف واحد يتجاوز @ لتحديد DR حدودي ، لكني أتردد في استخدام @ لشيء آخر . من الرموز الموجودة أعلى الصف العلوي من لوحة المفاتيح ، من المحتمل أن تكون أقل من !( ، @( ، $( ، ^( ، *( ، =( . أعتقد أن $ و ^ غير مبتدئين ، و =( يبدو نوعًا ما حزينًا ، لذلك يتبقى لديك !( و @( ، *( .

ترددي الوحيد مع * هو أنه في البداية يبدو وكأنه بداية عملية حسابية (وإن كانت مستحيلة) ، لكنني لا أشعر بقوة حيال ذلك.

بخلاف ذلك ، أعتقد أن غرائزك جيدة ، وأن مصمم الرمز الفردي الخاص بـ DRs البارامترية ذكي. تعجبني هذه الفكرة وهي تتماشى جيدًا مع الجهود المنفصلة لمحاذاة سلوك mixin / DR. 👍

بالتفكير في الأمر أكثر ، أعتقد أنني أحب .( أكثر لأنه يبدو تمامًا مثل "mixin w / o name" :) على الرغم من أنني أدرك أنه من الأفضل على الأرجح أن تكون شيئًا ملحوظًا.

نشر هذا فقط من أجل الأطراف المهتمة لتتمكن من محاولة العثور على إيجابيات وسلبيات مختلفة للقرارات (المتطرفة في بعض الأحيان) التي تم إجراؤها في المكون الإضافي قبل اتخاذ قرار بشأن تفاصيل الميزات الأساسية المقابلة

في غضون ذلك ، يتوفر إصدار الإنتاج من عبارات .for و .for-each المستندة إلى المكوّن الإضافي السابق بعملة less-plugin-lists . راجع الوثائق (لا تفوت الجزء المتقدم ) والاختبارات المضمنة ( 1 ، 2 ).

ملاحظة: هذه عبارات فعلية ، أي أنها لا تغطي حالات استخدام دالة رد النداء for-each (والتي سيتم تنفيذها أيضًا ... أيضًا ، كدالة عندما يكون لدينا بالفعل عمليات نداء بارامترية أو نوعا ما).

تم وضع علامة على هذه المشكلة تلقائيًا على أنها قديمة نظرًا لعدم وجود نشاط حديث لها. سيتم إغلاقه إذا لم يحدث أي نشاط آخر. شكرا لمساهماتكم.

تم وضع علامة على هذه المشكلة تلقائيًا على أنها قديمة نظرًا لعدم وجود نشاط حديث لها. سيتم إغلاقه إذا لم يحدث أي نشاط آخر. شكرا لمساهماتكم.

لقد صادفت هذا المنفذ Bootstrap v4 Less ، وهذا هو الشخص الذي من الواضح أنه يستخدم أقل قدرًا كبيرًا ، ونقص بناء الجملة for/each في أقل إثارة في الصفحة الافتتاحية: https://github.com/seanCodes / bootstrap-less-port

وهو ما يعني أنه لا يزال يمثل مشكلة. أعتقد أن هناك عددًا قليلاً من سلاسل المحادثات المبدئية هنا التي توفر الاحتمالات ، لكنني أتساءل عما إذا كنا لا نستطيع فعل شيء جيد مع القواعد المضمنة ، والقواعد المنفصلة ، والمزج. يعتمد هذا على بعض التعليقات حول @ seven-stage-max حول سلبيات "تمرير" المكرر في صيغة تشبه الوظيفة. بدلاً من ذلك ، يجب أن يأتي فقط في النهاية ، إما كمجموعة قواعد عادية ، أو مجموعة قواعد منفصلة var ، أو اسم mixin.

كما في:

[each syntax] [local vars] [ruleset|dr|mixin]

لذلك ، على سبيل المثال:

.foo {
  :each(<strong i="13">@key</strong>, <strong i="14">@value</strong> in @list) {
    @{key}: @value;
  }
}

// or

<strong i="15">@dr</strong>: {
  @{key}: @value;
};
.foo {
  :each(<strong i="16">@key</strong>, <strong i="17">@value</strong> in @list) @dr;
}

// or
.mixin(<strong i="18">@key</strong>, @value) {
  @{key}: @value;
}
.foo {
  :each(<strong i="19">@key</strong>, <strong i="20">@value</strong> in @list) .mixin;  
  // or   :each(<strong i="21">@key</strong>, <strong i="22">@value</strong> in @list) > .mixin;  ?
}

يمكنك أيضًا ، مثل @arguments ، حقن <strong i="26">@key</strong>, @value إذا تم توفير @list فقط. كما في:

.foo {
  :each(@list) .mixin
}

لست متأكدًا مما إذا كان :each هو الصيغة الصحيحة ، لكن الصيغة العادية each() لا معنى لها لأنها ليست بناء جملة وظيفي ، وأعتقد أننا نتفق مع @each() بالفعل برنامج non-starter for Less ، والذي يستخدم @ لقواعد at و vars والمكالمات المتغيرة بالفعل.

:each() سيجعل "محدد سلوك خاص" مثل :extend() ، وهو أمر منطقي بالنسبة لي. خواطر مرحب بها.

أتساءل عما إذا كان كل من :extend() و :each() يجب ألا يكون ::extend() و ::each() لتقليد المحددات الزائفة ::before و ::after . أنا لا أعرف ، فقط بناء جملة spitballin. بناءً على هذا الموضوع ، أعتقد أن هذا هو أفضل "بناء" من حيث القواعد ، ولكن لست متأكدًا من بناء الجملة الخاص بكيفية اعتماد each على وجه التحديد.

🤔 في الفكر الثاني ، :: غير ضروري. من الأفضل الحفاظ على بناء الجملة خفيفًا.

🤔 في الفكر الثاني ، :: غير ضروري. من الأفضل الحفاظ على بناء الجملة خفيفًا.

يوافق على. أعتقد أيضًا أنه أكثر انسجامًا مع الفئات الزائفة التي تقبل معاملات مثل :not() و :nth-child() ، وأعتقد أن :: يُستخدم فقط للعناصر الزائفة ، على أي حال (على سبيل المثال . المحددات الزائفة التي تغير الهدف الفعلي للمحدد بدلاً من تغيير قائمة التطابقات ، مثل ::before أو ::placeholder ).

بالنسبة إلى :each() نفسها ، فأنا حقًا معجب بهذا الاقتراح. جدا "ص". تعتبر Mixins مشكلة بالتأكيد ، لكنني أتساءل عما إذا كنا نسمي ذلك خارج نطاق التنفيذ الأولي. أعتقد أن الحاجة كبيرة بما يكفي لأن حل DR فقط من شأنه أن يخفف الضغط على المكتبات مثل bootstrap-less-port.

سأقول ، مثل :extend() ، يجب أن يكون محددًا زائفًا لـ real ، مما يعني أننا يجب أن نطلب &:each() بدلاً من :each() فقط إذا كان متداخلًا.

.foo:each(<strong i="20">@list</strong> as <strong i="21">@i</strong>, @item) {
  &-@{i} { item: @item; }
}
// OR
.foo {
  &:each(<strong i="22">@list</strong> as <strong i="23">@i</strong>, @item) {
    &-@{i} { item: @item; }
  }
}

هناك خيار آخر وهو القاعدة ، التي تحتوي بالفعل على بنية [name] (params) {ruleset} في CSS. أعترف بأنني أشعر بقليل من "Sass-y" ، لكنها تبدو نظيفة حقًا.

<strong i="28">@each</strong> (<strong i="29">@list</strong> as <strong i="30">@i</strong>, @item) {
  .foo-@{i} { item: @item; }
}

على الرغم من ذلك ، في الواقع ، يمكن أن تكون نفس النظافة ممكنة مع & ، طالما أن :each() يسمح بـ "محدد أساسي" فارغ.

&:each(<strong i="35">@list</strong> as <strong i="36">@i</strong>, @item) {
  .foo-@{i} { item: @item; }
}

هل هذا يعقد كيف يفكر الناس حول &:extend() ، حيث أن هذا الشخص _ لا يمكن أن يكون لديه محدد قاعدة فارغ؟

SIDEBAR: هذه فكرة لخيط آخر ويوم آخر (إذا كان لها أي ميزة على الإطلاق) لكنني أعلم أن التردد في المزيد من القواعد هو دليل على المستقبل. سيكون خيارًا ، على الأرجح (¿ربما --prefix-at-rules / -@ ، ربما أخذ قائمة من القواعد إلى البادئة؟) وأنا أعرف كيف يحب الجميع إضافة الخيارات.


بشكل مضحك بما فيه الكفاية ، seanCodes ، الرجل الذي لا يمتلك منفذًا ، هو أخي. سأحاول الحصول عليه هنا لإضافة 2 ¢.

سأقول ، مثل: extension () ، يجب أن يكون محددًا زائفًا لـ real ، مما يعني أننا يجب أن نطلب &: each () بدلاً من مجرد: كل () إذا كانت متداخلة.

_للمتعة الكافية_ ، كنت أميل إلى التوصية (بشكل منفصل) بأن لا يحتاج $ # :extend &:extend . أعني ، هذا المعنى ليس غامضًا بدون & .

ولكن فيما يتعلق بـ &:each ، عليك أن تضع في اعتبارك أنك قد ترغب في حلقات من القوائم _إنشاء محددات_في المقام الأول. لكن .... أقل لا يمانع & في الجذر. 🤔

هناك خيار آخر وهو at-rule ، والذي يحتوي بالفعل على بنية [name] (params) {ruleset} في CSS. أعترف بأنني أشعر بقليل من "Sass-y" ، لكنها تبدو نظيفة حقًا.

نعم ، أنت لست مخطئا. وربما يكون @each أكثر تشابهًا من الناحية المعنوية مع @media . لا يمكنني أن أقرر حقًا ، لأنه لا يوجد مكافئ CSS حقيقي في اللغة. من المحتمل أن تكون أكثر شبهاً بالوظائف من حيث أنها توجيه تقييم. إنها مجرد وظائف محرجة لحالة الاستخدام هذه للتخصيص لمجموعة القواعد.

المفهوم ليس صعبًا هنا ؛ انها حقا حول بناء الجملة. وربما لا نحتاج إلى الحساسية تجاه بناء جملة Sass. أنا فقط أتساءل عما يجب أن يكون عليه "التوسيع التصريحي".

ربما يكون &:each ، في الواقع ، ليس سيئًا ، لأنك تقوم بشكل أساسي بدمج النتائج في النطاق الحالي أو المحدد أو غير ذلك.

بشكل مضحك بما فيه الكفاية ، seanCodes ، الرجل الذي لا يمتلك منفذًا ، هو أخي. سأحاول الحصول عليه هنا لإضافة 2 ¢.

ها! عالم صغير! إذن لماذا لم يكن في فريق Less أيضًا؟ الضحك بصوت مرتفع

تضمين التغريدة

أحد اقتراحات بناء جملة fave الخاصة بي في هذا الموضوع هو من @ seven-stage-max ، حيث يجعلها تشبه الوظيفة ، ولكن مع تعيين إلى "lambda" ، مثل هذا:

each(@list): (@value) {
    box-shadow+: <strong i="9">@value</strong> black;
}

الشيء الجميل في الأمر أنه سهل للغاية. إنها تشبه الوظيفة ، وتخصص لشيء يبدو وكأنه مزيج مجهول. ربما تكون محقًا في هذا التعليق: "تعتبر Mixins مشكلة بالتأكيد ، لكنني أتساءل عما إذا كنا نسمي ذلك خارج نطاق التنفيذ الأولي. أعتقد أن الحاجة كبيرة بما يكفي بحيث يخفف حل DR فقط من الضغط على مكتبات مثل bootstrap-less-port. "

بعد كل شيء ، يمكنك فقط القيام بما يلي:

each(@list): (@value) {
    .my-mixin(@value);
}

ومن ثم يمكن أن يكون المزيج الداخلي الخاص بك عندما ينتقل الحراس أو أي شيء للقيم إليه. اعتمادًا على طبيعة قائمتك ، يمكن أن تكون بعد ذلك:

each(@list): (<strong i="17">@key</strong>, @value) {
   // Obvs can also just put your rules in here too
    .my-mixin(<strong i="18">@key</strong>, @value);
}

أتساءل عما إذا كانت صيغة :each &:each إنه حقًا أكثر من توجيه وظيفي ، وليس حقًا مثل :extend على الإطلاق. كما أنها لا تضيف in أو as ككلمات رئيسية إلى بناء الجملة.

أعني ، لقد مرت بضع سنوات وما زالت هذه التركيبة قائمة بالنسبة لي. وهو أكثر ملاءمة لإنشاءات مثل:

.rules(@val) when (@val=warning) { ... }
.rules(@val) when (default()) { ... }

each(@selectors): (@value) {
  .badge-@{value} {
    .rules(@value);
  }
}

الكلمة الأساسية الوحيدة التي يمكنني إضافتها هي شيء مثل الكلمة الرئيسية to لهذا:

each(1 to 10): (@i) {
  <strong i="7">@val</strong>: extract(<strong i="8">@list</strong>, @i);
  .mixin(@val);
}

ثم بالطبع اجعل قيم 1 أو 10 فقط ، لذلك يمكنك القيام بما يلي:

<strong i="14">@start</strong>: 1;
each(<strong i="15">@start</strong> to length(@list)): (@i) {
  <strong i="16">@val</strong>: extract(<strong i="17">@list</strong>, @i);
  .mixin(@val);
}

أوه ، شيء آخر ، إذا كان هذا مجرد "مزيج مجهول" ، يجب أن تكون قادرًا على القيام بشيء مثل:

each(@colors): (@color) when (hue(@color) < 60) {
  background+: @color;
}

هذا هو ، يمكن أن يكون لدى mixins حراس ، هذا كل شيء. إنها ليست مشكلة كبيرة ، ولكن يجب فقط استدعاؤها من أجل الاتساق.

أحد اقتراحاتي اللغوية المفضلة

حسنًا ، لست متأكدًا من أنني أحب هذا النحو. إنه شعور غريب جدًا على Less و CSS ، وهو في الواقع غريب من جميع النواحي. إنها تقريبًا ، ولكنها ليست وظيفة تمامًا. يبدو أنه مجرد مفهوم آخر لجعل الناس يتعلمون.

إنه حقًا توجيه وظيفي أكثر ...

اهتمامي الرئيسي بهذا هو أن CSS (AFAIK) لا يستخدم أبدًا وظائف باستثناء داخل قيم الخصائص. التوجيهات على مستوى الجذر هي دائمًا في القواعد.

كما أنه لا يضيف أو ككلمات رئيسية إلى بناء الجملة.

يبدو أنه يستخدم فقط : بدلاً من الكلمة الأساسية. وهو ما يرام. ربما يكون من الصعب قراءتها.

&:each(<strong i="15">@list</strong>:@i) {
  /* rules */
}
<strong i="16">@each</strong> (<strong i="17">@list</strong>:@i) {
  /* rules */
}

بما يكفي ، كنت أميل إلى أن أوصي (بشكل منفصل) ألا يحتاج $ # $ :extend &:extend . أعني ، هذا المعنى ليس غامضًا بدون & .

أنا أحب & في &:extend . إنها تبقي من الواضح أن :extend() هي فئة زائفة. يتطلب التمديد قاعدتين (أو محددات ، على ما أعتقد) ، القاعدة الحالية والأخرى التي يجب تمديدها. يربط بناء الجملة هذا :extend بالمحددات بطريقة لطيفة. لست متأكدًا من أن شخصية واحدة تستحق العناء والالتواء المفاهيمي.

الكلمة الأساسية الوحيدة التي يمكنني إضافتها ...

أنا أحب to .

كنغمة جانبية ، بدأ هذا يشعر وكأنه أكثر من for وأقل من each . (يبدو أن "كل" تشير فقط إلى كل مجموعة ، أي قائمة / مصفوفة ، بينما "For" تبدو وكأنها تشير إلى فهارس أكثر عشوائية.) أعتقد أن كلمة "for" هي كلمة أكثر مرونة ، من وجهة نظر دلالية .

حقًا ، على الرغم من ذلك ، نظرًا لأن هذا كله يتعلق بالصياغة ، أعتقد أن أفضل شيء يمكن فعله هو الاقتراض من اللغات التي من المرجح أن يعرفها المستخدمون الأقل.

<strong i="39">@for</strong> (<strong i="40">@i</strong> in @list) {
  <strong i="41">@item</strong>: extract(<strong i="42">@i</strong>, @list);
  /*stuff*/
}

كلمة أخرى أكثر وضوحًا هي loop .

<strong i="47">@loop</strong> @list(<strong i="48">@i</strong>, @item) {
  /* stuff */
}

بالتفكير أكثر حول :each() ، لا أعتقد أنه يحتاج إلى & . يمتلك :extend() _ شيئًا يجعله امتدادًا لمعلماته. ليس من المنطقي أن تكون "محددًا" بمفردها. لكن هذا ليس صحيحًا بالنسبة للفئات الزائفة _most_ css. :nth-child() ، :not() ، :lang() ، وما إلى ذلك ، _ all_ يمكن أن تكون قائمة بذاتها ولها معنى. لا يوجد سبب لايمكن :each() . في الواقع ، :extend() هو نوعًا ما _ غريب_ بهذه الطريقة.

:each(<strong i="14">@list</strong> @i) { // no reason this should error
  /* stuff */
}

مما يعني أن السؤال الأساسي هو: @ أو : أو دالة / دالة قريبة.

اهتمامي الرئيسي بهذا هو أن CSS (AFAIK) لا يستخدم أبدًا وظائف باستثناء داخل قيم الخصائص. التوجيهات على مستوى الجذر هي دائمًا في القواعد.

صحيح ، ولكن اعتبارًا من أقل من 2.7 ، لا توجد قيود على مكان استدعاء الوظائف. لكني فهمت وجهة نظرك.

أنا لست ضد for على الرغم من أن @for ..... 🤔 أعني أن الكثير من اللغات تستخدم forEach أو for-each . ونعم ، أعتقد أن هذا كله يتعلق بالمكان الذي تشعر فيه بقلة الجلوس في مساحة اللغة. دائمًا ما يكون قرار الإضافة إلى اللغة أمرًا صعبًا.

أعتقد أنني أحاول معرفة ما هو موازي لما حدده cloudhead مع بناء جملة حماية mixin ، والذي كان اختيارًا متعمدًا للغاية مقابل if . أي أنه كان "تقييم هذا في ظل هذه الظروف". كانت مجموعة من الشروط للتقييم. أي if يمكن رؤيته بهذه الطريقة أيضًا ، أريد فقط أن أكون مخلصًا لمقصد اللغة. إنه تغيير كبير ، مهما كانت الحاجة واضحة.

بالنسبة لي ، لا ينقل :each(<strong i="5">@list</strong> @i) {} أو :each(<strong i="7">@list</strong>: @i) { الطبيعة التكرارية للتقييم بشكل صحيح. يبدو أنه تقييم لمرة واحدة ، أي أن @i يساوي القيمة الكاملة لـ @list . في حين أن شيئًا مثل :each(@list): (@i) { } يجعل الأمر أكثر وضوحًا أن هناك مهمة تحدث لبنية تشبه mixin.

أنا لست ضد :each() مقابل each() للجزء الأول. لدي المخاوف هناك.

ماذا عن....

:each(@list) > (@val) { } 

هل > أقل إساءة للغة من : ؟ أنت محق في أنه ربما لا ينتمي هناك. أعتقد أنني أحببت "الشعور الدلالي" لبناء الجملة.

-
ربما :for(<strong i="23">@val</strong> in @list) { } أكثر نظافة؟ ربما أنت محق في أنه يعمل بشكل أفضل من البدء بالقائمة؟

@ Seven-stage-max كان :for (<strong i="5">@val</strong> in @list) في هذا التعليق جنبًا إلى جنب مع المتغيرات الأخرى for .

calvinjuarez هل تفضل شيئًا مثل:

:for (<strong i="7">@val</strong> in @list) {}
:for (<strong i="8">@key</strong>, <strong i="9">@val</strong> in @list) {}
:for (<strong i="10">@i</strong> in 1 to 10) {}

أشعر بالفضول بشأن ما يجب أن يقوله seanCodes عما سيكون أكثر منطقية وأيضًا "أقل تشابهًا" عند نقل Bootstrap.

أريد فقط أن أكون مخلصًا لمقصد اللغة. إنه تغيير كبير ، مهما كانت الحاجة واضحة.

هذه نقطة جيدة. كل ما نقوم به لا يمكن "التراجع عنه" حقًا. أعتقد أننا في هذه المرحلة ربما نحتاج إلى الحصول على مزيد من المدخلات.

هذه نقطة جيدة. كل ما نقوم به لا يمكن "التراجع عنه" حقًا. أعتقد أننا في هذه المرحلة ربما نحتاج إلى الحصول على مزيد من المدخلات.

انت على حق. لكن هذا الموضوع أيضًا ظل مفتوحًا ... [مخطوطات للخلف] .... أربع سنوات. أعني ، في مرحلة ما تبذل قصارى جهدك وتتخذ قرارًا. لكني أحب الوصول إلى شيء قريب من الإجماع.

لكن نعم ، لا داعي للعجلة ، فلنرى ما إذا كان هناك اهتمام متجدد بالتوصل إلى توافق.

هل تفضل شيئًا مثل: ...

نعم ، أعتقد أن كل هؤلاء نظيفون حقًا. على الرغم من أن هذا يحتوي على مشكلة الكلمات الرئيسية التي ذكرتها ، حيث تتم إضافة in و to . لكنني أعتقد أن وضوحها قد يكون يستحق التكلفة؟

أنا فضولي ما يجب أن يقوله seanCodes ...

نفس. سأقتبس ما ورد أعلاه حتى يحصل على إشعار آخر.

[مخطوطات للخلف] .... أربع سنوات.

كلمة.

يختار أحدكم بما يمكنه في ذلك الوقت:
https://github.com/seven-phases-max/less-plugin-lists

TigersWay - وهو أمر رائع ، ولكنه يستخدم أيضًا ما كان متاحًا ، على سبيل المثال ، عدم عمل شيء قد يختنقه المحلل اللغوي ، لذلك فهو يستعير من بناء جملة mixin. من الناحية المثالية سيكون هناك شيء أصلي. على الرغم من أن هذه المشكلة قد تم فتحها لمدة أربع سنوات ، إلا أن حلقات IMHO الأقل كانت .... أقل من مثالية ... من البداية. معظم الأمثلة التكرارية هي مجرد اختراقات متكررة لحراسة mixin. مرة أخرى ، فقط رأيي.

نعم

في ذللك الوقت

ولكن بعد 4 سنوات ، التصويت / اتخاذ القرار بنفوسين قصير نوعًا ما.
وأنا لست أحد :-)

معظم الأمثلة التكرارية هي مجرد اختراقات متكررة لحراسة mixin.

لا الخارقة. مجرد حلقات قائمة على العودية.
إنها الطريقة التي تكتب بها حلقة بلغة برمجة وظيفية.

أقل يعتمد بشكل كبير على مبادئ FP بفضل طبيعته التصريحية. على النقيض من الطبيعة الحتمية لـ Sass.

لا الخارقة. مجرد حلقات قائمة على العودية. إنها الطريقة التي تكتب بها حلقة بلغة برمجة وظيفية.

rjgotten حسنًا ، نقطة عادلة. لكن أعني أنه على الرغم من أنه يمكن تقييمها بشكل متكرر ، إلا أنها تصنع بناء جملة محرجًا. ولكن أيضًا ، لكي نكون منصفين ، حتى لغة نماذج توضيحية مثل XSLT بها علامة for-each . ( https://msdn.microsoft.com/en-us/library/ms256166 (v = مقابل 110) .aspx) لذا فإن تقييم النوع for-each ليس إلزاميًا فقط. حتى في أقل ، لا يزال تعريفًا لأنه "ملزم" أساسًا بالتكرار بالتقييم for-each . الاختلاف الوحيد في أمر حتمي لكل منهما هو أنه يمكنك فعل شيء مثل تغيير حالة القيم أو كسر الحلقة. في تقييم الحلقة التصريحية ، يتم "توسيع" كل تكرار وتقييمه مقابل شرط. لذلك لا يمكنك أبدًا "كسر" الحلقة ، ولكن يمكنك إعداد شروط تقيد القيم التي تمر.

بمعنى آخر ، طريقة التفكير في for-each كما تنطبق على Less هي كما يلي:

.rule {
  .mixin(extract(<strong i="15">@list</strong>, 1));   // This was an `each` call of some sort on <strong i="16">@list</strong>
  .mixin(extract(<strong i="17">@list</strong>, 2));
  .mixin(extract(<strong i="18">@list</strong>, 3));
  .mixin(extract(<strong i="19">@list</strong>, 4));
  .mixin(extract(<strong i="20">@list</strong>, 5));
  .mixin(extract(<strong i="21">@list</strong>, 6));
}

سيتم تقييم كل شيء ودمجه في قواعد الوالدين. لهذا السبب كنت أدافع عن نموذج "خلط مجهول" يسمح للحراس.

سأقول إنني أشاركك قلقك من أننا يجب أن نكون مترددين بشأن بناء الجملة الذي _ يشبه_ شكلًا ضروريًا. يجب أن تنقل بوضوح فكرة "توسيع" القائمة إلى مكالمات. مثل ، في Less ، لن ترغب أبدًا في شيء مثل:

<strong i="26">@for</strong> (<strong i="27">@i</strong> = 0; <strong i="28">@i</strong> < length(@list); <strong i="29">@i</strong> = <strong i="30">@i</strong> + 1) {}

هذا أمر حتمي ولا معنى له. على وجه الخصوص ، في أقل <strong i="33">@i</strong> = <strong i="34">@i</strong> + 1 لا معنى له. يمكن أن يكون للمتغير قيمة واحدة لكل نطاق. لا يمكن للغة التقريرية أو لا ينبغي أن تغير حالتها.

:for (<strong i="37">@i</strong> in 1 to 10) {} مختلف قليلاً لأن i يتم تخصيص قيمة واحدة لكل توسع mixin .... لكن .... لا تزال "حتمية مثل"؛ هذا هو السبب في أنني كنت أفضّل نوعًا من "المهمة" من :each ، مثل :each(@list): (@val) أو :each(@list) > (@val) أو :for(@list):select(@val) أو شيء من هذا القبيل.

@ ماثيو دين
أنت محق تماما. هناك فرق حاسم بين الحلقة الحتمية for والطبيعة التعريفية للحلقة for-each . أردت بالفعل أن أكتب المزيد عن ذلك ، لكنك هزمتني.

rjgotten ^ _ ^ منذ أن فتحت هذا الموضوع ، هل لديك أي اقتراحات للمضي قدمًا؟ إنه نوع الميزة التي أرغب في رؤيتها ، لكن يبدو أن بناء الجملة يصعب حقًا الحصول عليه بشكل صحيح.

rjgotten بالمناسبة ، عندما كنت أعيد قراءة هذا كتبت:

يبدو أن LESS حاليًا يدعم فقط مجموعات القواعد "الصافية" لتمريرها كوسائط mixin أو تخزينها في متغيرات كمجموعات قواعد منفصلة.

يجب أن أشير إلى أنه في Less 3.5 beta ، قمت بتنفيذ تعيين استدعاءات mixin إلى المتغيرات أو تمريرها إلى مزيج آخر ، وفقًا للاقتراح الموجود في https://github.com/less/less-meta/issues/12.

كما في:

.foo {
  <strong i="12">@call</strong>: .some-mixin(42);
  @call();
  .other-mixin(.some-mixin(42));
}

هل هذا يساعد هذه القضية على الإطلاق أو يبلغها بقدر الاتجاه؟

هل هذا يساعد هذه القضية على الإطلاق أو يبلغها بقدر الاتجاه؟

لا ، للأسف لا يساعد.

لكي تكون mixins قادرة على العمل كـ "lambdas" ، يجب أن تكون قادرًا على تعيين mixin _itself_ كمعامل ، وليس _ النتيجة _ لاستدعاء mixin. على سبيل المثال

<strong i="9">@list</strong> : a b c;
.iteration-mixin(@item) {
  // does something with each <strong i="10">@item</strong> ...
}

:for-each(<strong i="11">@list</strong>, .iteration-mixin);

وإذا أخذنا توحيد القواعد المنفصلة والمزج على طول الطريق ويمكننا دعم "المزيجات المجهولة" (المعروفة أيضًا باسم مجموعات القواعد المنفصلة) القادرة على أخذ المعلمات ، فيمكننا دعم بناء الجملة مثل:

<strong i="15">@list</strong> : a b c;
:for-each(<strong i="16">@list</strong>, (@item) {
   // does something with each <strong i="17">@item</strong> ...
});

أعتقد أن هذا سيكون قمة البنية سهلة الاستخدام التي يمكن أن تقدمها اللغة للتكرار فوق القوائم.

rjgotten أنا لا أعارض هذا الشكل أيضًا ، والذي أعرف أنه مشابه لما قدمته لأول مرة. ربما أفضل تقصيرها إلى :each شخصيًا. هل هناك أي شيء تشعر به أكثر من الناحية اللغوية أو التصريحية لـ for-each على each ؟

ولكن ، عمليًا ، أحصل على ما تريده لتحقيق الاتساق ، وإدراج مجموعة القواعد كجزء من نموذج "الاتصال" ليس بالأمر السيئ.

أوافق أيضًا ، كما يمكنك أن تتخيل من مناقشاتنا في المواضيع الأخرى ، في الشكل العام (@var) { } الذي يمكن أن يكون بناء لغة يستخدم في أي مكان (مثل "مزيج مجهول").

هل ستكون ضد هذا الشكل؟

<strong i="14">@list</strong> : a b c;
:each(<strong i="15">@list</strong>, (@item) {
   // ...
});
:each(<strong i="16">@list</strong>, (<strong i="17">@item</strong>, @key) {
   // ...
});

أنا قلق قليلاً بشأن المكان المناسب لهذا في مساحة اللغة جنبًا إلى جنب مع :extend() و & when .

أنا فقط لا أحب @each . أنا لست ضد وظيفة each() عادية لأن التحليل يحتاج إلى تغييرات أقل (إذا تم السماح لمجموعات القواعد المنفصلة) ، لكنني أفهم أيضًا رد الفعل من البعض على رؤية الوظائف العادية في الجذر. يسعدني أن أرى هذه المناقشة ما زالت تمضي قدمًا!

أوه ، أنا أحب ذلك! أعتقد أننا إذا مررنا فقط القواعد ، فيجب أن تكون وظيفة. لا أعتقد أننا يجب أن نقدم ميزة أخرى شبيهة بالمحدد ولا تتطلب أي مجموعة قواعد. :extend(); غريب حقًا بهذه الطريقة.

calvinjuarez هل يمكنك التوضيح؟ هل ستدافع عن دالة each() عادية ، بالنظر إلى هذه المعلمات؟

أنت تعرف؛ إذا كنت تفكر في ذلك ، فإن :each( ... ) حقًا _ هو مجرد وظيفة عادية في الجذر.
إنها وظيفة تسمى ": كل" ​​(بما في ذلك القولون).
إذن من حيث التنفيذ لا ينبغي أن يكون هناك فرق حقيقي ، أليس كذلك؟ إذا كان الأمر كذلك ، فيمكن التبديل بسهولة إلى الميزة مع / بدون النقطتين وربما حتى مع كون النقطتين اختياريتين.

يقودني هذا إلى نقطة أخرى: ربما ينبغي أن نجعل تلك النقطة النقطية ميزة اختيارية لأي استدعاء دالة جذر؟

انظر أولاً إلى دالة لا تحتوي على جذر: property : func( ... )
ثم انظر إلى دالة الجذر: : func( ... )

إنه نفس الشيء ، مع اختلاف واحد: نسخة الجذر بها الجانب الأيسر "مفقود" ، لأنه في الواقع يتم تعيين النتيجة _directly_ إلى - أي الإخراج إلى - النطاق الحالي ، بدلاً من تعيينها إلى خاصية.

rjgotten يمكنك بالفعل وضع الوظائف في الجذر منذ 2.7. لست متأكدًا من سبب جعل القولون اختياريًا لأي وظيفة؟ هل تعتقد أن هذا مفضل من حيث النحو؟

من ناحية التنفيذ ، نعم ، سيكون هناك تغيير بسيط في المحلل اللغوي للتعرف على الوظيفة إذا كانت النقطتان اختياريًا ، لكن هذا ليس سببًا لعدم القيام بذلك إذا كان مفضلًا لهذه الحالة.

شيء واحد ، قد نبلغ مؤلفي الإضافات بشكل أوضح أنه يمكنك وضع وظائف في الجذر إذا جعلناها دالة each() بسيطة.

تعال إلى التفكير في الأمر ، ربما يجب علينا إنقاذ استخدام بادئة القولون هنا.
قد يؤدي إلى التباس في القواعد ، لأنه يشبه الفئات الزائفة مثل :nth-child()

وحقا؛ لا أحد يريد صداع الاضطرار إلى التعامل مع ذلك مرة أخرى ، في مكان ما أسفل الخط.

تعال إلى التفكير في الأمر ، ربما يجب علينا إنقاذ استخدام بادئة القولون هنا.
قد يؤدي إلى التباس في القواعد ، لأنه يشبه الفئات الزائفة مثل: nth-child ()

👍

حسنًا ، هل نحن أقرب إلى الإجماع على جعل هذه وظيفة مضمنة each() تمر فيما نسميه إما "مزيج مجهول" أو "مجموعة قواعد منفصلة مع معلمات"؟ أعتقد أنه يجب أن يكون الأخير في قاعدة الكود حتى نتمكن من توحيد نوعي استدعاء مجموعة القواعد.

إذا كنا أقرب ، أود نشر هذا السؤال:

بالنظر إلى أن شخصًا ما قد يكون لديه قوائم مفاتيح / قيم ، أو يريد فهرسًا ، وهو أكثر "الطريق الأقل" ->

each(<strong i="13">@list</strong>, (@value) { }); // and...
each(<strong i="14">@list</strong>, (<strong i="15">@key</strong>, @value) { });
// or
each(<strong i="16">@list</strong>, (@value) { }); // and...
each(<strong i="17">@list</strong>, (<strong i="18">@value</strong>, @key) { });

على عكس JavaScript ، يكون عدد الوسائط في أقل مهمًا. لذلك لا يوجد سبب برمجي لوضع القيمة دائمًا أولاً ، لأن المفتاح لن يتم _set_ (يتم تمريره كمعامل) ما لم يكن هناك _ تعريف مطابق_.

لذا فأنا أميل إلى القول إن (<strong i="22">@key</strong>, @value) هو أكثر من أقل من y. إذا كان لديك وسيطتان في تعريفك ، فسيتم تمرير وسيطتين. إذا لم يكن الأمر كذلك ، فسيتم تمرير القيمة.

سأذهب بالفعل إلى (<strong i="5">@value</strong>, @key) نظرًا لأن @value في 99٪ من الحالات ما ستكرره و @key هو شيء ثانوي ربما تستخدمه في معالجة.

كما أن لديها تكافؤًا مع تكرار forEach في JavaScript.
وعلى الرغم من أن الأقل ليس جافا سكريبت ؛ دعونا نواجه الأمر ، كلاهما يعمل في الواجهة الأمامية وسيكون هناك الكثير من الأمثلة على مساحة ذهنية مشتركة للمطورين هناك. قد يكون كذلك أسهل بالنسبة لهم.

سأذهب بالفعل إلى (<strong i="6">@value</strong>, @key) نظرًا لأن @value في 99٪ من الحالات ما ستكرره و @key هو شيء ثانوي ربما تستخدمه في معالجة.

هذا جيد بالنسبة لي. أنا جيد مع الحجة القائلة بأن @key ثانوي ولا يتعلق تمامًا بتكافؤ JS ، على الرغم من أنه من الجيد أنه يشترك في مساحة العقل ، كما تقول.

أنا أحب مكان هذا! نعم ، أنا مع الوظيفة البسيطة.

each(<strong i="6">@list</strong>, (<strong i="7">@item</strong>, @i) {});

واضح وبسيط.

تضمين التغريدة

بالمناسبة ، قمت بعمل نسخة من هذا بدون تغييرات تحليلية منذ أكثر من عامين بقليل. انظر الالتزامات على هذا الفرع: https://github.com/matthew-dean/less.js/tree/feature/each

الطريقة التي قمت بها بدون تغييرات التحليل هي أن المعلمة الثانية يمكن أن تكون قائمة ، كما في: each(@list; key, value; {}); Buuuut أدركت أن هذا ليس مثاليًا.

الشيء هو ، إذا أردنا أن تكون قيمة (<strong i="12">@item</strong>, @i) {} قيمة شرعية ، فإني أرى بعض المشكلات:

  1. هل (<strong i="16">@item</strong>, @i) {} شكل من أشكال مجموعة قواعد منفصلة يمكن استخدامها في أي مكان؟ إذا تم استخدامه فقط مع each() ولا يمكن استخدامه مع أي وظيفة أخرى ، فلماذا؟
  2. إذا كان من الممكن استخدامه في مكان آخر ، فما هو؟ هل هو mixin أم مجموعة قواعد منفصلة ، لأن أ) إذا كانت مجموعة قواعد منفصلة ، فإن قواعد الحجج ليست تافهة. إذا لم تكن نفس الوسائط مثل mixins ، فلماذا لا؟ ب) إذا كان mixin ، حسنًا كيف يعمل ذلك؟ هل يمكن أن يكون لها حراس؟ يجب حل كل هذا الخيط بشكل أساسي: https://github.com/less/less-meta/issues/16

بشكل أساسي ، سيجعل هذا النموذج مجموعة القواعد أشبه بمزيج ، وهو أمر جيد ، لأننا نريد أن نصنع "شيئًا" واحدًا. ولكن بعد ذلك يجب تحديد مجموعة واحدة من القواعد.

لذلك ، يمكننا حل المشكلة من خلال عدم السماح بهذا "الشكل" ذي القيمة في أي مكان آخر ، والتغطية الخاصة بـ each() المضمن. (لن تكون الوظيفة الوحيدة ذات الغلاف الخاص ، لأن if يمكن أن تتلقى "عندما تكون الظروف" ، ولا يمكن لأي وظيفة أخرى.) بدلاً من ذلك ، يمكننا تجنب أي تغييرات تحليلية و "ضخ" متغيرين خاصين في الكتلة ، تمامًا مثل @arguments الآن. هذا هو ما فعلته بشكل افتراضي في التنفيذ الخاص بي. يمكننا حقن @key و @value في كل تكرار لمجموعة القواعد. بصراحة ، هذا أسهل ، لأنني قمت بالفعل بالعمل لول.

لذا فإن الأسهل ، والذي يمكن تنفيذه اليوم ، هو في الأساس:

each(<strong i="30">@list</strong>, {
  prop-@{key}: @value;
});

ما لم نقم بحالة خاصة / تحليل لكل منها ، لكن وظائف الغلاف الخاصة وقاعدة جديدة لكل args تستغرق وقتًا.

أفكار؟

أفكار؟

يبدو إدخال المعلمتين جيدًا كخطوة أولى لإخراج الميزة والعمل ، ثم إعادة الزيارة لإضافة أسماء معلمات مناسبة قابلة للتكوين من قبل المستخدم بمجرد مسح مشكلات مجموعة القواعد المنفصلة في مقابل المزيج.

تضمين التغريدة

يبدو إدخال المعلمتين جيدًا كخطوة أولى لإخراج الميزة والعمل ، ثم إعادة الزيارة لإضافة أسماء معلمات مناسبة قابلة للتكوين من قبل المستخدم بمجرد مسح مشكلات مجموعة القواعد المنفصلة في مقابل المزيج.

هذا جيد من قبلي. @key و @value حسنًا؟

إذا كنا سنقوم بالتكرار فوق القوائم فقط ، فسأستخدم @index بدلاً من @key ،
إذا كنا سنقوم بدعم التكرار عبر الخصائص (على سبيل المثال ، مجموعة قواعد منفصلة ، تُستخدم كخريطة / قاموس) أكثر من أن يكون @key أكثر ملاءمة.

إذا كنا سنقوم بدعم التكرار عبر الخصائص (على سبيل المثال ، مجموعة قواعد منفصلة ، تُستخدم كخريطة / قاموس) أكثر من أن يكون @key أكثر ملاءمة.

هذا بالضبط ما كنت أفكر فيه. أنها ستدعم التكرار على القوائم أو مجموعة القواعد كخرائط.

rjgotten يمكننا أيضًا إدخال اسم var مختلف اعتمادًا على نوع القائمة ، طالما تم توثيق الاسم الذي يجب استخدامه. سيكون من التافه تحديد ما إذا كانت مجموعة قواعد أم لا كقائمة.

في الواقع ، قد نرغب في تنفيذ @key AND @index@value ) ، في حالة رغبة شخص ما في القيام بشيء مع موضع القاعدة في الخريطة. بالنسبة للقوائم البسيطة ، يمكن تعيين قيمة @key على @index ، على الأقل مفاجأة.

@ ماثيو دين
(...)
أنت محق تماما. "مجموعة القواعد كخرائط" هي خرائط مرتبة حسب التعريف ، لذا فإن الفهرس يكون منطقيًا بالنسبة لها أيضًا.

في الواقع ، قد نرغب في تنفيذkey ANDindex ( وvalue) ، في حالة رغبة شخص ما في القيام بشيء ما باستخدام موضع قاعدة في الخريطة.

هذا يجعلني أتساءل عما يعنيه @index في سياق الخريطة. بمعنى أنه في حلقة القائمة ، يمكنك استدعاء extract() وتمرير الفهرس. يبدو أن هناك الكثير من المحاذير والتناقضات المقدمة بهذه الطريقة (على سبيل المثال ، extract(@looped-thing, @index) يعمل في بعض الحلقات ، ولكن ليس كلها).

<strong i="13">@map</strong>: {
  foo: bar;
  baz: qux;
};
each(<strong i="14">@map</strong>, {
  -less-log: extract(<strong i="15">@map</strong>, @index); // → ???
  // Or would this mean anything? (Certainly after a unification of access and extract that I've seen floated.)
  -less-log: @map[@index]; // → ???
})

لذلك ، أثناء تنفيذ هذا ، واجهت مشكلة each() المتداخلة ، وأتساءل عما إذا كنا بحاجة إلى معلمات مسماة. في محاولة لتسمية المعلمات باستخدام (<strong i="7">@value</strong>, @key) { } ، أدركت أن هذا كان غامضًا للتحليل ، إذا أردنا لاحقًا إجراء "الخلطات المجهولة" أو "مجموعات القواعد المنفصلة مع args". بمجرد كتابة <strong i="9">@dr</strong>: (@value ... حتى ذلك الحين ، يمكن أن ينتهي هذا بـ <strong i="11">@dr</strong>: (<strong i="12">@value</strong> + 1); أو <strong i="14">@dr</strong>: (<strong i="15">@value</strong>, @key) { } ، لذلك يفرض التراجع.

وهذا يعني نقطتين:

  1. المتغيرات المسماة مطلوبة إذا كنت تريد إنشاء وظائف متداخلة each() . كأول تطبيق ، ربما لا تكون هناك حاجة إليها؟ ربما لم تعالج التعشيش في البداية؟ ولكن إذا كنت تريدهم لاحقًا .... كيف سنقوم بالتوفيق بين المحقون مقابل المعلن؟
  2. أردت فقط أن أوضح أن هذا النموذج الخاص بالخلطات المجهولة / dr-args <strong i="22">@dr</strong>: (<strong i="23">@value</strong>, @key) { } غامض جدًا حقًا.

ربما شيء من هذا القبيل في المستقبل:

<strong i="27">@dr</strong>: #(<strong i="28">@arg1</strong>, @arg2) { };
@dr(1, 2);

each(<strong i="29">@list</strong>, #(<strong i="30">@value</strong>, @key) { });

لذا ، الشيء هو ، إذا كنت تريد التعشيش في أي وقت ، فربما يكون حقن vars هو النهج الخاطئ. وإذا كنت بحاجة إلى متغيرات مُسماة ، فعندئذٍ فقط (<strong i="33">@value</strong>, @key) { } لـ DR args هو النهج الخاطئ IMO for Less.

أو ربما يكون هذا هو الأسلوب الخاطئ لدعم each() . لا أدري...

<strong i="6">@dr</strong>: #(<strong i="7">@arg1</strong>, @arg2) { };

كنت أفكر في بعض المحددات لتوضيح أنك تحدد مزيجًا. أعتقد أن . يجب أن يكون مقبولاً أيضًا ، نظرًا لأن الخلطات القياسية "nonymous" تسمح إما . أو # .

بعبارة أخرى ، من الناحية المفاهيمية ، نقوم فقط بتوسيع نموذج _current_ mixin ليشمل بدون حرف بعد . أو # ، على الرغم من أنهم لن يتصرفوا بالطريقة التي ستتصرف بها الخلطات القياسية ، من حيث أنها لن تكون "قابلة للاستدعاء للمؤلف" ، ولن تسمح "بالحمل الزائد" (لأنها ستحدد مزيجًا فريدًا لمرة واحدة بدلاً من الإضافات الموجودة.

تضمين التغريدة

هذا يجعلني أتساءل ماذا تعني index في سياق الخريطة. هذا يعني أنه في حلقة القائمة ، يمكنك استدعاء extract () وتمرير الفهرس. يبدو أن هناك الكثير من المحاذير والتناقضات الناتجة بهذه الطريقة.

لا أرى أي تناقضات تظهر هناك. يمكنك تغيير المثال الخاص بك إلى شيء يعمل مع العلاقات العامة الحالية.

<strong i="11">@map</strong>: {
  foo: bar;
  baz: qux;
};
.box {
  each(<strong i="12">@map</strong>, {
    -less-log: @map[$@key]; 
  })
}

النواتج:

.box {
  -less-log: bar;
  -less-log: qux;
}

يمكنك أيضًا القيام بما يلي:

<strong i="19">@list</strong>: a b c d;
.box {
  each(<strong i="20">@list</strong>, {
    -less-log: extract(<strong i="21">@list</strong>, @index);
  })
}

أي نواتج:

.box {
  -less-log: a;
  -less-log: b;
  -less-log: c;
  -less-log: d;
}

أو هل تشير ببساطة إلى أنه لا يمكنك بالفعل استخدام @index إلى extract() على الخريطة؟ لأنني أعتقد أن هذه قضية منفصلة تمامًا.

بعبارة أخرى ، من الناحية المفاهيمية ، نقوم فقط بتوسيع صيغة mixin الحالية لتشمل عدم وجود حرف بعد. أو # ، على الرغم من أنهم لن يتصرفوا بالطريقة التي تتصرف بها الخلطات القياسية ، من حيث أنها لن تكون "قابلة للاستدعاء للمؤلف".

من المحتمل أن يكون المؤلف قابلاً للاستدعاء في النهاية ، ولكن لا يمكن الاستدعاء يمكن أن يعمل مع حالة الاستخدام الأولى هذه؟ تساءلت عن أيهما أختار: #( أو .( ، لكني أحب فكرة إما / أو.

-less-log: @map[$@key];

$@var يعمل !؟ لا يوجد لدي فكرة! اعتقدت أنه تم إلغاء! هذا يجعلني سعيدة جدا!

@ $ يعمل !؟ لا يوجد لدي فكرة! اعتقدت أنه تم إلغاء! هذا يجعلني سعيدة جدا!

ها ، نعم ، لقد تراجعت في إصلاحات الأخطاء قبل أن أفرج عن الإصدار 3.5. ^ _ ^

من المحتمل أن يكون المؤلف قابلاً للاستدعاء في النهاية ، ولكن لا يمكن الاستدعاء يمكن أن يعمل مع حالة الاستخدام الأولى هذه؟

أعتقد أن كلمة "مجهول" ستشير إلى "لا يمكن استدعاء المؤلف" ، ولكن ربما "مجهول" ليست هي الكلمة. ربما هذا شيء مختلف.

أيضًا (وقمت بتحرير التعليق الآخر بهذه الفكرة أيضًا ، لكنني سأضعه هنا حتى لا يكون مخفيًا) ، أعتقد أن الاختلاف _major_ هو أن .(){} و #(){} لن تكون مفرطة التحميل / قابلة للتكديس.

each(@list1; .(<strong i="11">@value</strong>, <strong i="12">@key</strong>, @i) {})
each(@list2; .(<strong i="13">@value</strong>, <strong i="14">@key</strong>, @i) {}) // this mixin probably shouldn't overload, right?

وهذا يعني أن المؤلفين لن يكون لديهم طريقة محددة للإشارة واستدعاء mixin .(){} المحدد ، وهو ما يعني أن كلمة "مجهول" هي ما هم عليه ويمكننا فقط أن نطلق عليهم هذا الأمر بشكل مباشر.

تضمين التغريدة

ألن نفعل هذا في النهاية؟

<strong i="8">@mixin</strong>: #(<strong i="9">@op1</strong>, @op2) {
  value: <strong i="10">@op1</strong> + @op2;
}
@mixin(2px, 1px);

والسبب هو ما قلته: أي لا يمكن تحميل الفارز بشكل زائد. لذلك يمكنك بشكل أساسي "استبدال" mixins عن طريق إعادة تعيين المتغير.

<strong i="14">@mixin</strong>: #(<strong i="15">@op1</strong>, @op2) {
  value: <strong i="16">@op1</strong> + @op2;
}
& {
  <strong i="17">@mixin</strong>: #(<strong i="18">@op1</strong>, @op2) {
    value: <strong i="19">@op1</strong> - @op2;
  }
  @mixin(2px, 1px);
}

يبدو وكأنه نمط مفيد إلى حد ما. يمكنك أيضًا تمرير تعريفات mixin إلى مزيج آخر ، وهو ما لا يمكنك فعله الآن. (في 3.5 يمكنك تمرير mixin _calls_ أي القواعد الناتجة إلى mixin ، لكن ليس التعريفات.) هذا هو المكان الذي كنت أذهب إليه ؛ وهذا هو سبب الحاجة إلى البادئة.

إذا كانت مجموعات القواعد المنفصلة مفيدة في التمرير والاتصال ، فمن المنطقي أن تكون مجموعات القواعد ذات القواعد مفيدة / قوية ، إن لم يكن أكثر من ذلك.

لهذا السبب أود أن يكون هذا النمط ، إذا تم استخدامه مقابل each() ، شيئًا يمكن تعميمه في مرحلة ما.

أعتقد أن كلمة "مجهول" ستقترح "لا يمكن استدعاء المؤلف"

تأتي "المجهول" في "الوظيفة المجهولة" من حقيقة أنها مبنية بدون مرجع مسمى خاص بها.

بدون المرجع المسمى الخاص به ، لا يمكن الوصول إليه مباشرة من خلال الاسم بالرمز في مواقع أخرى. وبهذا المعنى ، فإن مثل هذه الوظيفة "ليست _directly_ author-callable" ، ولكنها تظل قابلة للاستدعاء إذا قام المؤلف بتعيين مرجع الوظيفة الأصلي إلى متغير.

لذا نعم "مزيج مجهول" هو بالتأكيد المصطلح الصحيح هنا.

rjgotten شكرًا ، هذا تفسير رائع.

ما رأيك في القرص النحوي / العلاقات العامة؟

أعتقد أن إضافة # أو . المضاف لها معنى كبير وليس فقط من وجهة نظر توضيح الغموض.

.( a ) { } إلى .foo( a) { } أقل من function( a ) { } إلى function foo( a ) { } في JavaScript.

تقرأ حرفيا على النحو التالي: "هنا أعلن عن مزيج" (الرائد . ) "الذي لن أعطي اسمًا للرجوع إليه مرة أخرى."

الصيغة البديلة الوحيدة التي قد تكون منطقية هي imho لاستنساخ بنية دالة السهم من JS و C # وما إلى ذلك وجعلها مثل:

each(@list; (<strong i="16">@value</strong>, <strong i="17">@key</strong>, @index) => { })

قد يعمل ذلك أيضًا ، ولكن من المحتمل أن يكون تنفيذه أصعب بكثير لأنه يتطلب الكثير من التطلع إلى الأمام من خلال قائمة الوسائط للعثور على علامة => ، بينما إذا وجدت .( أو #( تسلسل على رأسك تعلم بالفعل أنك تتعامل مع mixin مجهول دون الحاجة إلى الكثير - إن وجد - lookahead.

قد يعمل ذلك أيضًا ، ولكن من المحتمل أن يكون تنفيذه أصعب بكثير لأنه يتطلب الكثير من النظر إلى الأمام من خلال قائمة الوسائط للعثور على علامة => ، بينما إذا وجدت. (أو # (التسلسل في الرأس الذي تعرفه بالفعل كنت تتعامل مع mixin مجهول دون الحاجة إلى الكثير - إن وجد - lookahead.

أعني أن هذا هو السبب الرئيسي. #() / .() أسهل في التنفيذ ، لكنني لن أدفعه إذا لم تتماسك البنية مع الناس. إذا كان هلامًا ، فأعتقد أنه يعمل كما هو متوقع في https://github.com/less/less.js/pull/3263. يرجى مراجعة عندما تحصل على الفرصة!

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات