سمة (برمجة)
المحتويات
- from typing import Any, Callable, TypeVar
- قواعد البيانات متعددة القيم
- Rust
- p.innerHTML
- class Integer {
- // causes compiler message saying that
- HTML وJavaScript
- زوج السمة والقيمة
- القواعد وأنواع البيانات
- {
- {
- Swift
- C++
- };
- using std::string;
- }
- XML
- @log_call
- C
- @log_call
- #[inline]
- }
- Java
- }
- nodiscard
- C#
- func newFeature {
- Check me
- استخدام السمات
- int x;
- [Obsolete("This is obsolete", IsError = false)]
- struct =Debug Person {
- انظر أيضاً
- Python

بدايةً، في البرمجة كائنية التوجه، تُعد السمة مواصفةً تحدد خاصية لـ كائن أو عنصر أو ملف. كما قد تشير كذلك إلى القيمة المحددة أو تقوم بتعيينها لنسخة معينة من ذلك. وللتوضيح، ينبغي بمزيد من الدقة اعتبار السمات بمثابة بيانات وصفية. وغالباً وبشكل عام، تعتبر السمة خاصية لخاصية أخرى. ومع ذلك، في الاستخدام الفعلي، يمكن التعامل مع مصطلح السمة –وغالباً ما يُعامل– على أنه مكافئ لـ الخاصية اعتماداً على التقنية قيد المناقشة. وعادة ما تتكون سمة الكائن من اسم وقيمة. وبالنسبة للعنصر، قد يكونان نوعاً واسم فئة، بينما بالنسبة للملف، قد يكونان اسماً وامتداداً على التوالي. وفيما يلي تفاصيل أوسع عن ذلك.
from typing import Any, Callable, TypeVar
- T = TypeVar("T")
- def log_call(func: Callable[..., T]) -> Callable[..., T]:
- @wraps(func)
- def wrapper(*args: tuple[int, ...], **kwargs: dict[str, str]) -> T:
- print(f"Calling {func.__name__} with args={args}, kwargs={kwargs}")
- return: T = func(*args, **kwargs)
- print(f"{func.__name__} returned {result}")
- return result
- return wrapper
قواعد البيانات متعددة القيم
إضافةً إلى ذلك، وكانت أول قاعدة بيانات من هذا النوع هي نظام تشغيل بيك. وتشمل المنصتان الحاليتان يونيفرس التابعة لشركة Rocket U2 وكاشيه التابعة لشركة InterSystems.
ومن ناحية أخرى، في الكثير من أنظمة قواعد البيانات ما بعد العلائقية أو متعددة القيم، وبالنسبة لـ SQL، الجداول هي ملفات، والصفوف هي عناصر، والأعمدة هي سمات. وفي كل من قاعدة البيانات والشيفرة، يُعد مصطلح السمة مرادفاً للخاصية والمتغير، على الرغم من أنه يمكن تعريف السمات بشكل إضافي لتتضمن قيم وقيم فرعية.
Rust
وفي هذا الصدد، يتم تعريف الكثير من الماكروز في اللغة، ولكن يتم إنشاء ماكروز جديدة باستخدام الماكروز الإجرائية. وفيما يلي بعض الأمثلة على استخدام الماكروز الموجودة:
// Marks a function as inline
وفي هذا السياق، في رست (Rust)، بناء جملة السمة هو #[attr]، ويُوضع على أي رمز، أو حتى على العبارات. تعدل السمات طريقة تجميع الشيفرة أو سلوكها عن طريق إرفاق بيانات وصفية برمز ما. وفي رست، تعتبر السمات نوعاً من الماكرو الإجرائي (procedural macro)، والذي يعمل على بناء جملة رست عن طريق استهلاك وإنتاج الشفرة.
p.innerHTML
"input.checked: " + (input.checked ? 'true' : 'false') + ""
});
class Integer {
no_unique_address
private:
// causes compiler message saying that
[Obsolete("Use class NewClass instead", IsError = true)]
public class ObsoleteClass
HTML وJavaScript
عرض سمة الخاصية والحالة المحددة لمربع الاختيار عند تغيرها.
<!doctype html>
زوج السمة والقيمة
- حقل (علوم الحاسوب)
- بيانات وصفية
- المراجع
- sl:Atribut alt
القواعد وأنواع البيانات
من جانب آخر، القواعد: كل سمة مسماة لها مجموعة مرتبطة من القواعد تسمى عمليات: مثلًا، لا يجمع المرء الرموز أو يعالج مصفوفة أعداد صحيحة بنية بيانات المصفوفة بنفس الطريقة التي يعالج بها كائن صورة. ولا يعالج النصوص كما لو كانت من نوع الفاصلة العائمة (الأعداد العشرية).
وفي هذا السياق، فمثلاً، لا تُفك تشفير تنسيقات ملفات الصور (مثل JPEG، وPNG، وBMP) باستخدام نفس العمليات (مهما بدت الصور متشابهة – فهذه جميعها تنسيقات بيانات رسومية). وبالمثل، لا تستعمل لغة البرمجة نفس العمليات لتقييم أعداد من نوع الفاصلة العائمة والأعداد الصحيحة الطويلة المحددة النوع.
كذلك، مثلًا، في رسوميات الحاسوب، يمكن أن تحتوي كائنات الخطوط على سمات مثل السمك (بقيم حقيقية)، واللون (بقيم وصفية مثل البني أو الأخضر أو قيم محددة في نموذج ألوان معين مثل RGB)، وسمات التقطيع، وما إلى ذلك. ويمكن تعريف كائن الدائرة بسمات مشابهة إلى جانب نقطة الأصل ونصف القطر.وفيما يتعلق بأنظمة الحاسوب، تُعرف السمات بشكل خاص لتكون سمات قراءة أو كتابة لقراءة أو كتابة محددة.
في هذا الإطار، أنواع البيانات: ويترتب على ذلك أنه يمكن توسيع تعريف الكائن من خلال فرض تحديد أنواع البيانات والذي يمكن أن يتكون من تنسيق تمثيل، وقيمة افتراضية، وعمليات قانونية (قواعد) وتقييدات (مثل "لا يُسامح في القسمة على صفر")، حيث تنطوي جميعها بشكل محتمل على تحديد السمة، أو العكس يمكن للمرء أن ينظر إليها كسمات لنوع ذلك الكائن.
{
- // ...
- }
- public class NewClass
{
// ...
Swift
@available(iOS 17, *)
علاوةً على ذلك، في سويفت (Swift)، يُرمز للسمات بالحرف @، وتشير إلى بيانات وصفية إضافية للمترجم. ويمكن تجميعها في سمات الإعلان، وسمات الأنواع، وغلافات الخصائص، وسمات التزامن، وسمات منشئ واجهة المستعمل.
C++
ومن ناحية أخرى، أضافت C++11 السمات، وهي مؤشرات للمترجم تحمل بعض المعلومات. ومع ذلك، فهي إما معرفة قياسياً أو معرفة حسب التنفيذ، ولا يمكن إنشاء سمات مخصصة.
تدعم لغة C++ كلاً من السمات والتعليقات التوضيحية.
};
من جانب آخر، أضافت C++26 التعليقات التوضيحية (Annotations), والتي يمكن إنشاؤها، ويمكن الوصول إليها باستخدام البرمجة الانعكاسية، مما يسمح بإرفاق بيانات وصفية تعسفية.
import std;
using std::string;
- // some annotations defined in namespace wikipedia::examples
- using wikipedia::examples::Debug;
- using wikipedia::examples::EnumFlag;
- using wikipedia::examples::Rename;
- enum class =EnumFlag Toggle : uint8_t {
- OFF,
- ON,
- };
}
- // Point automatically implements traits Debug, Clone, PartialEq
- #[derive(Debug, Clone, PartialEq)]
- struct Point {
- x: i32,
- y: i32,
- }
من جانب آخر، تدعم رست كذلك #[derive(Ts...)]، والتي تُسمى "ماكروز الاشتقاق" (derive macros)، وتُستعمل لتنفيذ الخصائص (traits) تلقائياً.
XML
من جهة ثانية، ومن الأمثلة الجيدة عملية إسناد إكس إم إل للقيم إلى الخصائص (العناصر). لاحظ أن قيمة العنصر توجد قبل وسم النهاية (المنفصل)، وليس في العنصر نفسه. وقد يحتوي العنصر نفسه على عدد من السمات المعينة (NAME = "IAMAPROPERTY").
في هذا الإطار، في إكس إم إل (XML)، السمة هي بنية ترميز تتكون من زوج اسم/قيمة يوجد داخل وسم البداية أو وسم عنصر فارغ. وتستعمل لغات الترميز، مثل HTML وXML، السمات لوصف البيانات وتنسيقها.
ومن ناحية أخرى، إذا كان العنصر المعني يمكن اعتباره خاصية (CUSTOMER_NAME) لكيان آخر (فلنقل CUSTOMER)، فيمكن أن يكون للعنصر صفر أو أكثر من السمات (الخصائص) الخاصة به (حيث أن CUSTOMER_NAME من نوع TYPE = "KINDOFTEXT").
@log_call
return f"Hello, {name}!"
def greet(name: str) -> str:
C
أدخلت لغة C السمات في C23، تَبَعاً لما حدث في C++11.
@log_call
return a + b
def add(a: int, b: int) -> int:
#[inline]
- fn add(a: i32, b: i32) -> i32 {
- a + b
- }
- // Allows unused variables
- #[allow(unused_variables)]
- fn example {
- let x = 5;
}
- // Conditionally compiles the function if the platform is Windows
- #[cfg(target_os = "windows")]
- fn windows_only {
- println!("Running on Windows.");
Java
من جهة ثانية، تستعمل لغة جافا (Java) التعليقات التوضيحية لحمل بيانات وصفية على الرموز أو تنفيذ توليد الشفرة، ويمكن الوصول إليها باستخدام الانعكاس.
- abstract class Animal {
- public abstract void speak;
- public String getType {
- return "Generic animal";
- }
- }
- class Cat extends Animal {
- @Override
- public void speak {
- System.out.println("Meow!");
- }
- @Override
- public String getType {
- return "Cat";
- }
- }
}
- // class name ends with "Attribute"
- // but can be used as "Obsolete"
- public class ObsoleteAttribute : Attribute
- {
- public string Message { get; }
- public bool IsError { get; set; }
- public ObsoleteAttribute {...}
- public ObsoleteAttribute(string msg) {...}
- public ObsoleteAttribute(string msg, bool error) {...}
- }
- [Obsolete]
- [Obsolete("This is obsolete")]
- [Obsolete("This is obsolete", false)]
nodiscard
- int add(int a, int b, maybe_unused int c) {
- return a + b;
- }
C#
في هذا الإطار، يرى مستعملو اللغات الكثير من الأمثلة حيث تُستعمل السمات لمعالجة الاهتمامات المتقاطعة وغيرها من الاستخدامات الآلية أو المتعلقة بالمنصة. وهذا يولد انطباعاً خاطئاً بأن هذا هو الغرض المقصود منها حصراً.
كذلك، يُترك استخدامها المحدد كبيانات وصفية للمطور، ويمكن أن يغطي نطاقاً واسعاً من أنواع المعلومات حول أي تطبيق محدد والفئات والأعضاء التي لا تعتمد على نسخة معينة. كما يُترك قرار كشف أي سمة معينة كخاصية للمطور، وكذلك قرار استخدامها كجزء من إطار عمل تطبيقي أكبر.
علاوةً على ذلك، يتم تنفيذ السمات كفئات مشتقة وغالباً ما تُستعمل من قِبل خدمات بيئة تشغيل اللغة المشتركة (CLR)، مثل التوافقية مع نموذج مكون الكائنات (COM)، والاتصال عن بعد، والتسلسل (serialization)، ويمكن الاستعلام عنها أثناء التشغيل.
يوضح المثال كيفية تحديد السمات في C#:
إضافةً إلى ذلك، في لغة البرمجة سي شارب (C#)، السمات هي بيانات وصفية مُلحقة بحقل أو كتلة تعليمة برمجية مثل التجميعات (Assemblies)، والأعضاء، والأنواع، وهي تكافئ التعليقات التوضيحية في جافا. يمكن الوصول إلى السمات بواسطة كل من المترجم وبرمجياً من خلال الانعكاس (Reflection). على النقيض من ذلك، تُعد الخصائص في مصطلحات C# أعضاءً في فئة تُستعمل نحوياً مثل متغيرات النسخة (أو الفئة)، ولكنها مُنفّذة كزوج من دالتي الاسترجاع والتعيين (getter/setter). (في غياب دالة التعيين، تكون الخصائص للقراءة فقط).
func newFeature {
print("Only available on iOS 17+")
}
Check me
- document.getElementById('check1').addEventListener('change', function(e) {
- var input = this;
- var p = document.querySelector('p');
استخدام السمات
ومن جهة أخرى، إذا كان العنصر المعني يمكن اعتباره خاصية (CUSTOMER_NAME) لكيان آخر (فلنقل CUSTOMER)، فيمكن أن يكون للعنصر صفر أو أكثر من السمات (الخصائص) الخاصة به (حيث أن CUSTOMER_NAME من نوع TYPE = "KINDOFTEXT).
int x;
- public:
- nodiscard
- bool isPositive const noexcept {
- if (x > 0) likely {
- return true;
- }
- return false;
- }
[Obsolete("This is obsolete", IsError = false)]
وفي هذا الصدد، المعاملات الموضعية مثل المعامل الأول من نوع نص أعلاه هي معاملات لمشيد السمة. أما معاملات الأسماء مثل المعامل المنطقي في المثال فهي خاصية للسمة ويجب أن تكون قيمة ثابتة.
كذلك، يجب الإشارة إلى أن السمات تختلف عن توثيق إكس إم إل (XML documentation) الذي يحدد كذلك بيانات وصفية، ولكنه غير متضمن في التجميع المجمع وبالتالي لا يمكن الوصول إليه برمجياً.
struct =Debug Person {
- Rename("full name")
- string fullName;
- int age;
- };
انظر أيضاً
متغير (علوم الحاسوب)
Python
وفي هذا الصدد، في بايثون (Python)، تسمى السمات بالمزخرفات (decorators)، وهي أي كائن قابل للاستدعاء يمكنه توسيع أو تعديل دالة أخرى أو متغير أو فئة دون تغيير شفرتها المصدرية. يُرمز للمزخرف بالرمز @، ويظهر أعلى الإعلان.
from functools import wraps
📝 هل في هذه المقالة خطأ؟
إذا وجدت معلومة تحتاج تصحيحاً أو إضافة، أو أردت حذف المقالة، أرسل لنا طلباً وسنراجعه.
ما رأيك في هذه المقالة؟