একটি সাধারণ প্রশ্ন হল কিভাবে বিদ্যমান ব্লকের সংজ্ঞা পরিবর্তন করা যায়। উদাহরণস্বরূপ, আপনি একটি সংযোগ চেক যোগ করতে বা মান ইনপুটে একটি ক্ষেত্র পরিবর্তন করতে চাইতে পারেন।
সাধারণভাবে, জায়গায় একটি ব্লক সংজ্ঞা সংশোধন করা সম্ভব নয়।
কিভাবে একটি বিদ্যমান সংজ্ঞা সংশোধন করতে হয়
আপনি যদি বিদ্যমান ব্লক প্রকারের সংজ্ঞা পরিবর্তন করতে চান:
- ব্লক-কোড জেনারেটর সহ বিদ্যমান সংজ্ঞাটির একটি অনুলিপি তৈরি করুন।
- অনুলিপি পরিবর্তন করুন এবং আপনার টাইপ একটি নতুন নাম দিন.
-
Blockly.Blocks
এ আপনার নতুন সংজ্ঞা যোগ করুন।
কেন আমি সরাসরি একটি বিদ্যমান সংজ্ঞা সংশোধন করতে পারি না?
আপনি যদি একটি বিদ্যমান সংজ্ঞা সংশোধন করতে পারবেন না কেন তা জানতে আগ্রহী হন, পড়ুন। আমরা কিছু সম্ভাবনা বিবেচনা করব।
একটি বিদ্যমান সংজ্ঞা সরাসরি পরিবর্তন করুন
বিদ্যমান ব্লকের সংজ্ঞাটি সরাসরি পরিবর্তন করার দুটি উপায় রয়েছে: বানরপ্যাচিং এবং কোডটি কাঁটা। উভয়ই দৃঢ়ভাবে নিরুৎসাহিত করা হয়, কারণ আপনি কোড ভাঙার ঝুঁকি চালান যা মাঙ্কিপ্যাচ বা কাঁটাযুক্ত কোডের উপর নির্ভর করে। উভয় কৌশলই আপডেট এবং বাগ ফিক্স একত্রিত করা কঠিন করে তোলে। আরও তথ্যের জন্য, বানরপ্যাচিং সম্পর্কে কী দেখুন? এবং কাঁটা ব্লকলি ।
একটি বিদ্যমান সংজ্ঞা উপশ্রেণী
এটি আপনার কাছে কোনওভাবে বিদ্যমান সংজ্ঞাটি উপশ্রেণীতে ঘটতে পারে। দুর্ভাগ্যবশত, এটি সম্ভব নয় কারণ ব্লক সংজ্ঞাগুলি ক্লাস নয় - তারা মিক্সিন। উদাহরণস্বরূপ, একটি রঙের সম্পত্তি ওভাররাইট করার কোন উপায় নেই কারণ সংজ্ঞাটিতে রঙের বৈশিষ্ট্য নেই। পরিবর্তে, এটিতে একটি init
ফাংশন রয়েছে যা ব্লকে রঙের বৈশিষ্ট্য সেট করতে setColour
কল করে। যেহেতু কলটি init
ভিতরে রয়েছে, পুরো init
ফাংশনটি প্রতিস্থাপন না করে এটি প্রতিস্থাপন করার কোন উপায় নেই।
একটি বিদ্যমান সংজ্ঞায় একটি ফাংশন ওভাররাইট করুন
বিদ্যমান সংজ্ঞায় একটি ফাংশন ওভাররাইট করা সম্ভব:
Blockly.Blocks['existing_block'].init = function() {/*new function*/};
এটি কাজ করে, কিন্তু আপনাকে বিদ্যমান ফাংশনটি অনুলিপি এবং সংশোধন করতে হবে -- আপনি জাদুকরীভাবে শুধুমাত্র একটি লাইন প্রতিস্থাপন করতে পারবেন না। এর সাথে বেশ কয়েকটি সমস্যা রয়েছে:
- এটি সম্পূর্ণ সংজ্ঞাটি অনুলিপি এবং সংশোধন করার থেকে খুব বেশি আলাদা নয়।
- আপনি JSON-এ সংজ্ঞায়িত ব্লকের
init
ফাংশন পরিবর্তন করতে এটি ব্যবহার করতে পারবেন না, যেমন Blockly-এর অন্তর্নির্মিত ব্লক। কারণ অনুলিপি করার জন্য কোনোinit
ফাংশন নেই -- এটি রান টাইমে তৈরি হয়। - এটির জন্য আপনাকে JavaScript ব্যবহার করে আপনার ব্লক সংজ্ঞায়িত করতে হবে, যা স্থানীয়করণে সমস্যা সৃষ্টি করতে পারে।
init-এর ফলাফল ওভাররাইট করুন
একটি init
ফাংশনের "শুধু একটি লাইন প্রতিস্থাপন" করার একটি উপায় হল init
ফাংশনটিকে একটি ফাংশন দিয়ে প্রতিস্থাপন করা যা মূল init
ফাংশনকে কল করে এবং তারপর সেই কলের ফলাফলটি ওভাররাইট করে। উদাহরণস্বরূপ, নিম্নলিখিত কোডটি logic_null
ব্লকের রঙ পরিবর্তন করে:
const originalInit = Blockly.Blocks['logic_null'].init;
Blockly.Blocks['logic_null'].init = function() {
originalInit.call(this);
this.setColour(300);
}
দুর্ভাগ্যবশত, এটি মনে হয় কম দরকারী। যেমন:
সংযোগ চেক প্রসারিত করা বা কম-সীমাবদ্ধ ক্ষেত্র যাচাইকারী প্রয়োগ করা ব্লক-কোড জেনারেটর এবং ইভেন্ট হ্যান্ডলারদের দ্বারা তৈরি অনুমানগুলিকে বাতিল করতে পারে।
একটি মান ইনপুট দিয়ে একটি ক্ষেত্র প্রতিস্থাপন করা ব্লক-কোড জেনারেটর এবং ক্ষেত্র যাচাইকারীকে ভেঙে ফেলবে এবং ইভেন্ট হ্যান্ডলারগুলিকে ভেঙে ফেলতে পারে। স্থানীয়কৃত ব্লকের জন্য এটি করা অত্যন্ত কঠিন হতে পারে কারণ বিভিন্ন লোকেলের ফলে বিভিন্ন ধরনের এবং ইনপুট এবং ক্ষেত্রগুলির অর্ডার সহ ব্লক হতে পারে।
একটি JSON সংজ্ঞায় একটি কী-মান জোড়া ওভাররাইট করুন
যদি একটি ব্লকের জন্য JSON সর্বজনীনভাবে উপলব্ধ হয়, তাহলে পৃথক JSON মানগুলি ওভাররাইট করা সম্ভব হতে পারে। যেমন:
// Block definition.
blockJson = {...};
Blockly.Blocks['my_block'] = {
init: function() {
initJson(blockJson); // Called when the block is created.
}
}
// Third-party code.
blockJson.colour = 100;
যাইহোক, এটি শুধুমাত্র তখনই কাজ করে যদি JSON অবজেক্টটি সর্বজনীনভাবে উপলব্ধ থাকে, সংজ্ঞাটি স্পষ্টভাবে init
ফাংশনকে সংজ্ঞায়িত করে এবং init
ফাংশন initJson
কল করে। JSON-কে defineBlocksWithJsonArray
বা createBlockDefinitionsFromJsonArray
এ পাস করা হলে এটি কাজ করে না কারণ তৃতীয় পক্ষের এটি সংশোধন করার সুযোগ পাওয়ার আগে JSON প্রক্রিয়া করা হয়। (মনে রাখবেন যে ব্লকলির অন্তর্নির্মিত ব্লকগুলি createBlockDefinitionsFromJsonArray
ব্যবহার করে।)
কিন্তু যদি JSON এই ভাবে সংজ্ঞায়িত না হয়? JSON বৈশিষ্ট্যগুলিকে ওভাররাইট করা কি এখনও সম্ভব নয়? দুর্ভাগ্যবশত, না. সংজ্ঞাটিতে একটি init
ফাংশন রয়েছে (JSON নয়) এবং একটি init
ফাংশনকে JSON-এ রূপান্তর করার জন্য কোনও ফাংশন নেই।
// Doesn't work. There is no getJson() function.
const json = Blockly.Blocks['existing_block'].getJson();
json['message0'] = 'my new message0';
Blockly.Blocks['existing_block'].init = function () {
initJson(json);
};
পুনর্ব্যবহারের জন্য ডিজাইন
আপনি আপনার নিজস্ব কাস্টম ব্লকগুলি ডিজাইন করার সাথে সাথে আপনি সেগুলিকে এমনভাবে ডিজাইন করতে সক্ষম হতে পারেন যা পুনঃব্যবহারের প্রচার করে।
JSON পুনরায় ব্যবহার করুন
আপনার যদি দুটি ব্লক থাকে যা যথেষ্ট পরিমাণে একই রকম, আপনি একটি প্যারেন্ট JSON সংজ্ঞা তৈরি করতে পারেন এবং এটিকে চাইল্ড সংজ্ঞায় পুনরায় ব্যবহার করতে পারেন। যেমন:
const parentJson = {
// shared properties
};
Blockly.Blocks['child_block_1'] = {
init: function() {
initJson({...parentJson, colour: 100})
}
}
Blockly.Blocks['child_block_2'] = {
init: function() {
initJson({...parentJson, colour: 200})
}
}
আরেকটি বিকল্প হল আপনার JSON কে একটি সর্বজনীনভাবে উপলব্ধ বস্তুতে সংজ্ঞায়িত করা এবং সেই বস্তুটিকে আপনার init
ফাংশনে initJson
এ পাস করা। এটি অন্যদের জন্য পৃথক বৈশিষ্ট্য ওভাররাইট করা সম্ভব করে তোলে। আরও তথ্যের জন্য, JSON সংজ্ঞায় একটি কী-মান জোড়া ওভাররাইট দেখুন।
ফাংশন পুনরায় ব্যবহার করুন
ব্লকগুলি বেশ কয়েকটি স্ট্যান্ডার্ড ফাংশনকে সংজ্ঞায়িত করতে পারে, যেমন ব্লক-লেভেল ইভেন্ট হ্যান্ডলার, কাস্টম টুলটিপস, ফিল্ড ভ্যালিডেটর এবং মিউটেটরদের দ্বারা ব্যবহৃত ফাংশন, সেইসাথে কাস্টম আচরণ প্রদান করে এমন ফাংশন, যেমন একটি ফাংশন যা বাহ্যিক ডেটা থেকে ফিল্ডের মান সেট করে, যেমন একটি রোবটের হাতের বর্তমান অবস্থান।
ব্লক জুড়ে এই ফাংশনগুলি পুনরায় ব্যবহার করা সম্ভব হতে পারে।
একটি ড্রপডাউন ক্ষেত্র ব্যবহার করুন
আপনার কাছে যদি অপারেটর ব্যতীত যথেষ্ট পরিমাণে একই রকম ব্লকের সেট থাকে, তাহলে আপনি অপারেটরের জন্য একটি ড্রপডাউন ক্ষেত্র আছে এমন একটি একক ব্লক ডিজাইন করতে সক্ষম হতে পারেন। যেমন:
- অন্তর্নির্মিত
logic_operation
ব্লক অপারেটরand
এবংor
সহ একটি ড্রপডাউন ব্যবহার করে। - অন্তর্নির্মিত
math_arithmetic
ব্লক অপারেটর+
,-
,×
,÷
, এবং^
সহ একটি ড্রপডাউন ব্যবহার করে।
এই ধরনের ব্লকের জন্য কোড জেনারেটর লেখা সাধারণত একটু বেশি জটিল, তবে একাধিক ব্লক লেখা এবং বজায় রাখার চেয়ে এখনও সহজ।
একটি মিউটেটর ব্যবহার করুন
আপনার যদি ব্লকের একটি সেট থাকে যা একই প্রোগ্রামিং কাঠামোর বিভিন্ন বৈচিত্র্যের প্রতিনিধিত্ব করে, আপনি একটি একক ব্লক তৈরি করতে সক্ষম হতে পারেন যা একটি মিউটেটার ব্যবহার করে। উদাহরণস্বরূপ, বিল্ট-ইন controls_if
ব্লক if-then-else
স্টেটমেন্টের একাধিক বৈচিত্র উপস্থাপন করতে পারে।