تصميم جدول الرموز وتنفيذه في روبي
-
14-11-2019 - |
سؤال
أقوم ببناء محلل معجمي في روبي وأنا على وشك البدء في جمع الرموز وتخزينها في جدول الرموز.سؤالي الرئيسي حول تصميم الرمز وما إذا كان ينبغي أن يكون جدولًا ثابتًا (بمعنى أنه سيتم الاحتفاظ بجميع البيانات على مستوى الفصل) أو ما إذا كان ينبغي أن يكون على أساس مثيل على سبيل المثال.
الخيار 1:هيكل البيانات على مستوى الفصل
require 'SymbolTableEntry.rb'
class SymbolTable
@sym_table = Array.new(500)
def initialize()
end
def SymbolTable.add(element, index)
@sym_table[index] = element if element.is_a? SymbolTableEntry
end
def SymbolTable.to_s
pp @sym_table
end
end
باستخدام هذا المخطط، تحتوي فئة SymptomaTable على نوع من الوظائف "الثابتة"، مما يعني أنني لا أقوم فعليًا بإنشاء مثيل لـSymbolTable، والكائن الوحيد الموجود هو مستوى الفئة الأول.
(افترض أن SymbolTableEntry
هو كائن صالح على الرغم من أنني لا أعرفه هنا)
السابق:
irb(main):002:0> require 'SymbolTable.rb'
=> true
irb(main):003:0> ste = SymbolTableEntry.new
=> #<SymbolTableEntry:0x7ef36884>
irb(main):004:0> SymbolTable.add(ste, 10)
=> #<SymbolTableEntry:0x7ef36884>
irb(main):005:0> SymbolTable.to_s
[nil,
nil,
nil,
nil,
nil,
nil,
nil,
nil,
nil,
nil,
#<SymbolTableEntry:0x7ef36884>]
=> nil
الخيار 2:بنية البيانات على مستوى المثيل
require 'rubygems'
require 'backports'
require 'SymbolTableEntry.rb'
class SymbolTable
def initialize()
@sym_table = Array.new(10)
end
def add(element, index)
@sym_table[index] = element if element.is_a? SymbolTableEntry
end
def to_s
pp @sym_table
end
end
باستخدام هذا المخطط، سأحتاج فعليًا إلى إنشاء مثيل لفئة SymptomaTable لإضافة قيم إلى جدول الرموز.
irb(main):001:0> require 'SymbolTable.rb'
=> true
irb(main):002:0> st = SymbolTable.new
=> #<SymbolTable:0x7eeb6c9c @sym_table=[nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil]>
irb(main):003:0> ste=SymbolTableEntry.new
=> #<SymbolTableEntry:0x7eeb4d5c>
irb(main):004:0> st.add(ste,10)
=> #<SymbolTableEntry:0x7eeb4d5c>
irb(main):007:0> st.to_s
[nil,
nil,
nil,
nil,
nil,
nil,
nil,
nil,
nil,
nil,
#<SymbolTableEntry:0x7eeb4d5c>]
=> nil
أرغب في سماع أي وجميع المدخلات حول التصميم الذي ستستخدمه أو تفضل استخدامه، بالإضافة إلى أي تعليقات على كود روبي بشكل عام.
شكرًا
المحلول
تفضل متغيرات المثيل على متغيرات الفئة، إذا لم يكن هناك سبب آخر سوى أن الفئات التي تستخدم متغيرات الفئة تكون أكثر صعوبة في اختبار الوحدة.
يمكنك استخدام متغيرات الحالة ولا يزال لديك جدول رموز واحد للتحكم فيها جميعًا.إحدى الطرق هي تعيين جدول الرموز الخاص بك لمتغير عام:
$symbol_table = SymbolTable.new
في بعض اللغات، يصعب اختبار الفئات التي تستخدم المتغيرات العامة.في روبي، فهي ليست سيئة للغاية، نظرًا لأن كتابة البطة تتيح لك تعيين كائنات وهمية للمتغيرات العامة قبل تنفيذ الكائن قيد الاختبار.
أو يمكنك استخدام النمط المفرد.تأتي روبي مع مكتبة لتسهيل ذلك:
require 'singleton'
class SymbolTable
include Singleton
...
end
لاسترداد المثيل الوحيد لـSymbolTable، قم بإنشائه إذا لزم الأمر:
SymbolTable.instance
نصائح أخرى
استخدم متغيرات المثيل.ولكن ليس (على الأقل ليس فقط) لأسباب تتعلق بالتعامل مع الاختبار.بل بسبب
- ستنتج كل عملية تحليل جدول الرموز الخاص بها، لذلك قد يكون لديك أكثر من جدول رموز واحد في المرة الواحدة
- جدول الرموز مطلوب فقط طالما أن عملية التحليل جارية
- تقدم متغيرات الفئة ضرورة إجراء المزامنة لتحقيق أمان الخيط - على الرغم من أن كل عملية تحليل يمكن أن تتعايش بشكل جيد مع مجموعة الرموز الخاصة بها
هتافات
روبرت
مجرد توضيح سريع لاثنين من الإجابات التي قدمها روبرت وواين، وكلاهما يذكر متغيرات الطبقة.
لا يقترح السؤال الأصلي استخدام متغيرات الفئة على الإطلاق ولكنه يسأل عن الاستخدام متغيرات مثيل الفئة.استخدم الخيار الأول الذي قدمه Hunter كائن الفئة نفسه كمثيل واحد لجدول الرموز (مع الحالة المخزنة في متغيرات مثيل الفئة) بينما استخدم الخيار الثاني إطار فئة/مثيل أكثر نموذجية مع الحالة المخزنة في مثيل الرمز طاولة.
متغيرات فئة روبي ليست هي نفس متغيرات مثيلات الفئة ويجب تجنبها بشكل عام.