রাইনো রানটাইমটি ৩১শে জানুয়ারী, ২০২৬ তারিখে বা তার পর বন্ধ করে দেওয়া হচ্ছে। আপনার যদি রাইনো রানটাইম ব্যবহার করে এমন কোনো স্ক্রিপ্ট থাকে, তবে আপনাকে অবশ্যই স্ক্রিপ্টটি V8-এ মাইগ্রেট করতে হবে।
প্রায়শই একটি স্ক্রিপ্টে V8 সিনট্যাক্স এবং ফিচার যোগ করার একমাত্র পূর্বশর্ত হলো V8 রানটাইম সক্রিয় করা । তবে, কিছু অসামঞ্জস্যতা এবং অন্যান্য পার্থক্য রয়েছে, যার ফলে V8 রানটাইমে একটি স্ক্রিপ্ট ব্যর্থ হতে পারে বা অপ্রত্যাশিতভাবে আচরণ করতে পারে। যখন আপনি একটি স্ক্রিপ্টকে V8 ব্যবহারের জন্য মাইগ্রেট করবেন, তখন আপনাকে অবশ্যই স্ক্রিপ্ট প্রজেক্টে এই সমস্যাগুলো খুঁজে বের করতে হবে এবং যা কিছু খুঁজে পাবেন তা সংশোধন করতে হবে।
V8 মাইগ্রেশন পদ্ধতি
একটি স্ক্রিপ্টকে V8-এ স্থানান্তর করতে, এই পদ্ধতি অনুসরণ করুন:
- স্ক্রিপ্টটির জন্য V8 রানটাইম সক্রিয় করুন । Google Apps Script প্রজেক্টের ম্যানিফেস্ট ব্যবহার করে
runtimeVersionযাচাই করা যেতে পারে। - নিম্নলিখিত অসঙ্গতিগুলো মনোযোগ সহকারে পর্যালোচনা করুন। আপনার স্ক্রিপ্টে এই অসঙ্গতিগুলোর কোনোটি উপস্থিত আছে কিনা তা পরীক্ষা করুন; যদি এক বা একাধিক অসঙ্গতি উপস্থিত থাকে, তবে সমস্যাটি দূর করতে বা এড়াতে আপনার স্ক্রিপ্ট কোডটি পরিবর্তন করুন।
- নিম্নলিখিত অন্যান্য পার্থক্যগুলো মনোযোগ সহকারে পর্যালোচনা করুন। তালিকাভুক্ত পার্থক্যগুলোর কোনোটি আপনার কোডের আচরণকে প্রভাবিত করে কিনা তা নির্ধারণ করতে আপনার স্ক্রিপ্টটি পরীক্ষা করুন। আচরণটি সংশোধন করতে আপনার স্ক্রিপ্টটি সামঞ্জস্য করুন।
- একবার আপনি আবিষ্কৃত যেকোনো অসঙ্গতি বা অন্যান্য পার্থক্য সংশোধন করে নিলে, V8 সিনট্যাক্স এবং অন্যান্য বৈশিষ্ট্য ব্যবহার করার জন্য আপনার কোড আপডেট করা শুরু করুন।
- আপনার কোডে প্রয়োজনীয় পরিবর্তন আনার পর, স্ক্রিপ্টটি পুঙ্খানুপুঙ্খভাবে পরীক্ষা করে দেখুন যে এটি প্রত্যাশা অনুযায়ী কাজ করছে কিনা।
- আপনার স্ক্রিপ্টটি যদি একটি ওয়েব অ্যাপ বা প্রকাশিত অ্যাড-অন হয়, তবে আপনাকে অবশ্যই V8 পরিবর্তনগুলো সহ স্ক্রিপ্টটির একটি নতুন সংস্করণ তৈরি করতে হবে এবং ডেপ্লয়মেন্টটি নতুন তৈরি করা সংস্করণটির দিকে নির্দেশ করতে হবে। ব্যবহারকারীদের কাছে V8 সংস্করণটি উপলব্ধ করতে, আপনাকে অবশ্যই এই সংস্করণটি দিয়ে স্ক্রিপ্টটি পুনরায় প্রকাশ করতে হবে।
- যদি আপনার স্ক্রিপ্টটি একটি লাইব্রেরি হিসেবে ব্যবহৃত হয়, তাহলে আপনার স্ক্রিপ্টটির একটি নতুন সংস্করণ তৈরি করুন। আপনার লাইব্রেরি ব্যবহারকারী সমস্ত স্ক্রিপ্ট এবং ব্যবহারকারীদের এই নতুন সংস্করণটি সম্পর্কে জানান এবং তাদেরকে V8-সক্ষম সংস্করণে আপডেট করার নির্দেশ দিন। যাচাই করুন যে আপনার লাইব্রেরির কোনো পুরোনো, রাইনো-ভিত্তিক সংস্করণ আর সক্রিয়ভাবে ব্যবহৃত হচ্ছে না বা সহজলভ্য নয়।
- যাচাই করুন যে আপনার স্ক্রিপ্টের কোনো ইনস্ট্যান্স এখনও লিগ্যাসি রাইনো রানটাইমে চলছে না। যাচাই করুন যে সমস্ত ডেপ্লয়মেন্ট V8 সংস্করণের সাথে যুক্ত আছে। পুরোনো ডেপ্লয়মেন্টগুলো আর্কাইভ করুন। সমস্ত সংস্করণ পর্যালোচনা করুন এবং যে সংস্করণগুলো V8 রানটাইম ব্যবহার করছে না, সেগুলো মুছে ফেলুন।
অসামঞ্জস্যতা
মূল রাইনো-ভিত্তিক অ্যাপস স্ক্রিপ্ট রানটাইমটি দুর্ভাগ্যবশত বেশ কিছু নন-স্ট্যান্ডার্ড ECMAScript আচরণের অনুমতি দিত। যেহেতু V8 স্ট্যান্ডার্ড-সম্মত, তাই মাইগ্রেশনের পর এই আচরণগুলো আর সমর্থিত নয়। এই সমস্যাগুলো সংশোধন করতে ব্যর্থ হলে, V8 রানটাইম সক্রিয় করার পর ত্রুটি দেখা দেয় বা স্ক্রিপ্টের আচরণে সমস্যা তৈরি হয়।
নিম্নলিখিত বিভাগগুলিতে এই প্রতিটি আচরণ এবং V8-এ স্থানান্তরের সময় আপনার স্ক্রিপ্ট কোড সংশোধন করার জন্য আপনাকে যে পদক্ষেপগুলি নিতে হবে তা বর্ণনা করা হয়েছে।
for each(variable in object)
জাভাস্ক্রিপ্ট ১.৬-এ for each (variable in object) স্টেটমেন্টটি যোগ করা হয়েছিল এবং for...of সুবিধার জন্য এটি সরিয়ে ফেলা হয়।
আপনার স্ক্রিপ্ট V8-এ স্থানান্তর করার সময়, for each (variable in object) স্টেটমেন্ট ব্যবহার করা থেকে বিরত থাকুন ।
এর পরিবর্তে for (variable in object) ব্যবহার করুন:
// Rhino runtime var obj = {a: 1, b: 2, c: 3}; // Don't use 'for each' in V8 for each (var value in obj) { Logger.log("value = %s", value); } | // V8 runtime var obj = {a: 1, b: 2, c: 3}; for (var key in obj) { // OK in V8 var value = obj[key]; Logger.log("value = %s", value); } |
Date.prototype.getYear() পরিহার করুন।
রাইনোর মূল রানটাইমে, Date.prototype.getYear() ১৯০০ থেকে ১৯৯৯ সাল পর্যন্ত দুই-অঙ্কের বছর এবং অন্যান্য তারিখের জন্য চার-অঙ্কের বছর রিটার্ন করে, যা জাভাস্ক্রিপ্ট ১.২ এবং তার পূর্ববর্তী সংস্করণগুলোতে প্রচলিত ছিল।
ECMAScript মান অনুযায়ী, V8 রানটাইমে Date.prototype.getYear() ফাংশনটি বছর থেকে ১৯০০ বিয়োগ করে প্রাপ্ত মান রিটার্ন করে।
আপনার স্ক্রিপ্ট V8-এ স্থানান্তর করার সময়, সর্বদা Date.prototype.getFullYear() ব্যবহার করুন , যা তারিখ নির্বিশেষে একটি চার-অঙ্কের বছর ফেরত দেয়।
নাম হিসেবে সংরক্ষিত কীওয়ার্ড ব্যবহার করা পরিহার করুন।
ECMAScript ফাংশন এবং ভেরিয়েবলের নামে কিছু সংরক্ষিত কীওয়ার্ডের ব্যবহার নিষিদ্ধ করে। Rhino রানটাইম এই শব্দগুলোর অনেকগুলোই ব্যবহারের অনুমতি দিত, তাই আপনার কোডে যদি সেগুলো ব্যবহৃত হয়, তবে আপনাকে অবশ্যই আপনার ফাংশন বা ভেরিয়েবলের নাম পরিবর্তন করতে হবে।
আপনার স্ক্রিপ্ট V8-এ স্থানান্তর করার সময়, ভেরিয়েবল বা ফাংশনের নামে সংরক্ষিত কীওয়ার্ডগুলোর কোনো একটি ব্যবহার করা থেকে বিরত থাকুন । কীওয়ার্ডের ব্যবহার এড়াতে যেকোনো ভেরিয়েবল বা ফাংশনের নাম পরিবর্তন করুন। নাম হিসেবে কীওয়ার্ডের সাধারণ ব্যবহারগুলো হলো class , import , এবং export ।
এর একটি ব্যতিক্রম হলো যে, অবজেক্ট লিটারেলগুলো সংরক্ষিত কীওয়ার্ড ব্যবহার করতে পারে (সকল রানটাইমে):
function class() {} // Syntax error in V8. var obj = { class: 1 }; // Allowed.
const ভেরিয়েবল পুনরায় নির্ধারণ করা এড়িয়ে চলুন
রাইনোর মূল রানটাইমে, আপনি const ব্যবহার করে একটি ভেরিয়েবল ডিক্লেয়ার করতে পারেন, যার অর্থ হলো সিম্বলটির মান কখনও পরিবর্তন হয় না এবং ভবিষ্যতে সিম্বলটিতে করা যেকোনো অ্যাসাইনমেন্ট উপেক্ষা করা হয়।
নতুন V8 রানটাইমে, ` const কীওয়ার্ডটি স্ট্যান্ডার্ড-সম্মত এবং ` const হিসেবে ঘোষিত কোনো ভেরিয়েবলে মান অ্যাসাইন করলে TypeError: Assignment to constant variable রানটাইম এরর দেখা দেয়।
আপনার স্ক্রিপ্ট V8-এ স্থানান্তর করার সময়, কোনো const ভেরিয়েবলের মান পুনরায় নির্ধারণ করার চেষ্টা করবেন না :
// Rhino runtime const x = 1; x = 2; // No error console.log(x); // Outputs 1 | // V8 runtime const x = 1; x = 2; // Throws TypeError console.log(x); // Never executed |
XML লিটারেল এবং XML অবজেক্ট পরিহার করুন
ECMAScript-এর এই অ-প্রমিত সম্প্রসারণটি অ্যাপস স্ক্রিপ্ট প্রকল্পগুলিকে সরাসরি XML সিনট্যাক্স ব্যবহার করার সুযোগ দেয়।
আপনার স্ক্রিপ্ট V8-এ স্থানান্তর করার সময়, সরাসরি XML লিটারেল বা XML অবজেক্ট ব্যবহার করা থেকে বিরত থাকুন ।
এর পরিবর্তে, XML পার্স করার জন্য XmlService ব্যবহার করুন:
// V8 runtime var incompatibleXml1 = <container><item/></container>; // Don't use var incompatibleXml2 = new XML('<container><item/></container>'); // Don't use var xml3 = XmlService.parse('<container><item/></container>'); // OK |
__iterator__ ব্যবহার করে কাস্টম ইটারেটর ফাংশন তৈরি করবেন না।
জাভাস্ক্রিপ্ট ১.৭-এ একটি ফিচার যোগ করা হয়েছিল, যার মাধ্যমে যেকোনো ক্লাসের প্রোটোটাইপে একটি __iterator__ ফাংশন ডিক্লেয়ার করে সেই ক্লাসে একটি কাস্টম ইটারেটর যোগ করা যেত; ডেভেলপারদের সুবিধার জন্য এটি অ্যাপস স্ক্রিপ্টের রাইনো রানটাইমেও যুক্ত করা হয়েছিল। তবে, এই ফিচারটি কখনোই ECMA-262 স্ট্যান্ডার্ডের অংশ ছিল না এবং ECMAScript-সম্মত জাভাস্ক্রিপ্ট ইঞ্জিনগুলো থেকে এটি সরিয়ে ফেলা হয়। V8 ব্যবহারকারী স্ক্রিপ্টগুলো এই ইটারেটর কনস্ট্রাকশনটি ব্যবহার করতে পারে না।
আপনার স্ক্রিপ্ট V8-এ স্থানান্তরিত করার সময়, কাস্টম ইটারেটর তৈরি করতে __iterator__ ফাংশনটি ব্যবহার করা থেকে বিরত থাকুন । এর পরিবর্তে, ECMAScript 6 ইটারেটর ব্যবহার করুন।
নিম্নলিখিত অ্যারে গঠনটি বিবেচনা করুন:
// Create a sample array var myArray = ['a', 'b', 'c']; // Add a property to the array myArray.foo = 'bar'; // The default behavior for an array is to return keys of all properties, // including 'foo'. Logger.log("Normal for...in loop:"); for (var item in myArray) { Logger.log(item); // Logs 0, 1, 2, foo } // To only log the array values with `for..in`, a custom iterator can be used. |
নিম্নলিখিত কোড উদাহরণগুলিতে দেখানো হয়েছে কিভাবে রাইনো রানটাইমে একটি ইটারেটর তৈরি করা যেতে পারে, এবং কিভাবে V8 রানটাইমে একটি রিপ্লেসমেন্ট ইটারেটর তৈরি করতে হয়:
// Rhino runtime custom iterator function ArrayIterator(array) { this.array = array; this.currentIndex = 0; } ArrayIterator.prototype.next = function() { if (this.currentIndex >= this.array.length) { throw StopIteration; } return "[" + this.currentIndex + "]=" + this.array[this.currentIndex++]; }; // Direct myArray to use the custom iterator myArray.__iterator__ = function() { return new ArrayIterator(this); } Logger.log("With custom Rhino iterator:"); for (var item in myArray) { // Logs [0]=a, [1]=b, [2]=c Logger.log(item); } | // V8 runtime (ECMAScript 6) custom iterator myArray[Symbol.iterator] = function() { var currentIndex = 0; var array = this; return { next: function() { if (currentIndex < array.length) { return { value: "[${currentIndex}]=" + array[currentIndex++], done: false}; } else { return {done: true}; } } }; } Logger.log("With V8 custom iterator:"); // Must use for...of since // for...in doesn't expect an iterable. for (var item of myArray) { // Logs [0]=a, [1]=b, [2]=c Logger.log(item); } |
V8 রানটাইমে, কাস্টম ইটারেটর দিয়ে অ্যারে ট্র্যাভার্স করার সময় আপনাকে অবশ্যই for...of ব্যবহার করতে হবে, কারণ for..in ইটারেবল আশা করে না।
শর্তসাপেক্ষ ক্যাচ ক্লজ পরিহার করুন
V8 রানটাইম catch..if কন্ডিশনাল ক্যাচ ক্লজ সমর্থন করে না, কারণ এগুলো স্ট্যান্ডার্ড-সম্মত নয়।
আপনার স্ক্রিপ্টটি V8-এ স্থানান্তর করার সময়, যেকোনো ক্যাচ কন্ডিশনালকে ক্যাচ বডির ভিতরে নিয়ে যান :
// Rhino runtime try { doSomething(); } catch (e if e instanceof TypeError) { // Don't use // Handle exception } | // V8 runtime try { doSomething(); } catch (e) { if (e instanceof TypeError) { // Handle exception } } |
Object.prototype.toSource() ব্যবহার করা পরিহার করুন।
জাভাস্ক্রিপ্ট ১.৩-এ Object.prototype.toSource() নামে একটি মেথড ছিল যা কখনোই কোনো ECMAScript স্ট্যান্ডার্ডের অংশ ছিল না। এটি V8 রানটাইমে সমর্থিত নয়।
আপনার স্ক্রিপ্টটি V8-এ স্থানান্তর করার সময়, কোড থেকে Object.prototype.toSource() এর যেকোনো ব্যবহার সরিয়ে ফেলুন ।
অন্যান্য পার্থক্য
স্ক্রিপ্ট ব্যর্থতার কারণ হতে পারে এমন পূর্ববর্তী অসামঞ্জস্যগুলো ছাড়াও আরও কিছু পার্থক্য রয়েছে, যেগুলো সংশোধন না করা হলে V8 রানটাইম স্ক্রিপ্টের অপ্রত্যাশিত আচরণ দেখা দিতে পারে।
এই অপ্রত্যাশিত সমস্যাগুলো এড়ানোর জন্য আপনার স্ক্রিপ্ট কোড কীভাবে আপডেট করবেন, তা নিম্নলিখিত বিভাগগুলিতে ব্যাখ্যা করা হয়েছে।
স্থানীয় অঞ্চল-ভিত্তিক তারিখ এবং সময়ের বিন্যাস সামঞ্জস্য করুন
Rhino-এর তুলনায় V8 রানটাইমে toLocaleString() , toLocaleDateString() , এবং toLocaleTimeString() নামক Date মেথডগুলো ভিন্নভাবে কাজ করে।
রাইনোতে ডিফল্ট ফরম্যাট হলো লং ফরম্যাট , এবং এতে পাস করা যেকোনো প্যারামিটার উপেক্ষা করা হয়।
V8 রানটাইমে, ডিফল্ট ফরম্যাট হলো সংক্ষিপ্ত ফরম্যাট এবং প্রদত্ত প্যারামিটারগুলো ECMA স্ট্যান্ডার্ড অনুযায়ী পরিচালিত হয় (বিস্তারিত জানতে toLocaleDateString() ডকুমেন্টেশন দেখুন)।
আপনার স্ক্রিপ্টটি V8-এ স্থানান্তর করার সময়, লোকেল-নির্দিষ্ট তারিখ এবং সময় মেথডগুলির আউটপুট সম্পর্কিত আপনার কোডের প্রত্যাশাগুলি পরীক্ষা করুন এবং সামঞ্জস্য করুন :
// Rhino runtime var event = new Date( Date.UTC(2012, 11, 21, 12)); // Outputs "December 21, 2012" in Rhino console.log(event.toLocaleDateString()); // Also outputs "December 21, 2012", // ignoring the parameters passed in. console.log(event.toLocaleDateString( 'de-DE', { year: 'numeric', month: 'long', day: 'numeric' })); | // V8 runtime var event = new Date( Date.UTC(2012, 11, 21, 12)); // Outputs "12/21/2012" in V8 console.log(event.toLocaleDateString()); // Outputs "21. Dezember 2012" console.log(event.toLocaleDateString( 'de-DE', { year: 'numeric', month: 'long', day: 'numeric' })); |
Error.fileName এবং Error.lineNumber ব্যবহার করা পরিহার করুন।
V8 রানটাইমে, স্ট্যান্ডার্ড জাভাস্ক্রিপ্ট Error অবজেক্টটি কনস্ট্রাক্টর প্যারামিটার বা অবজেক্ট প্রপার্টি হিসেবে fileName বা lineNumber সমর্থন করে না।
আপনার স্ক্রিপ্টটি V8-এ স্থানান্তর করার সময়, Error.fileName এবং Error.lineNumber এর উপর থেকে যেকোনো নির্ভরতা দূর করুন ।
এর একটি বিকল্প হলো Error.prototype.stack ব্যবহার করা। এই স্ট্যাকটিও অ-মানক, কিন্তু V8-এ সমর্থিত। দুটি প্ল্যাটফর্ম দ্বারা উৎপাদিত স্ট্যাক ট্রেসের বিন্যাস সামান্য ভিন্ন:
// Rhino runtime Error.prototype.stack // stack trace format at filename:92 (innerFunction) at filename:97 (outerFunction) | // V8 runtime Error.prototype.stack // stack trace format Error: error message at innerFunction (filename:92:11) at outerFunction (filename:97:5) |
স্ট্রিং করা এনাম অবজেক্টের পরিচালনা সামঞ্জস্য করুন
রাইনোর মূল রানটাইমে, কোনো enum অবজেক্টের উপর জাভাস্ক্রিপ্টের JSON.stringify() মেথড ব্যবহার করলে শুধুমাত্র {} রিটার্ন হয়।
V8-এ, একটি enum অবজেক্টে একই মেথড ব্যবহার করলে enum-এর নামটি রিটার্ন হয়।
আপনার স্ক্রিপ্ট V8-এ স্থানান্তর করার সময়, enum অবজেক্টের উপর JSON.stringify() এর আউটপুট সম্পর্কিত আপনার কোডের প্রত্যাশাগুলো পরীক্ষা করুন এবং সামঞ্জস্য করুন :
// Rhino runtime var enumName = JSON.stringify(Charts.ChartType.BUBBLE); // enumName evaluates to {} | // V8 runtime var enumName = JSON.stringify(Charts.ChartType.BUBBLE); // enumName evaluates to "BUBBLE" |
অনির্ধারিত প্যারামিটারগুলির পরিচালনা সামঞ্জস্য করুন
রাইনোর মূল রানটাইমে, কোনো মেথডে প্যারামিটার হিসেবে ' undefined ' পাস করলে সেই মেথডে "undefined" স্ট্রিংটি পাস হয়ে যেত।
V8-এ, মেথডে undefined পাস করা null পাস করার সমতুল্য।
আপনার স্ক্রিপ্টটি V8-এ স্থানান্তর করার সময়, undefined প্যারামিটার সম্পর্কিত আপনার কোডের প্রত্যাশাগুলো পরীক্ষা করুন এবং সামঞ্জস্য করুন ।
// Rhino runtime SpreadsheetApp.getActiveRange() .setValue(undefined); // The active range now has the string // "undefined" as its value. | // V8 runtime SpreadsheetApp.getActiveRange() .setValue(undefined); // The active range now has no content, as // setValue(null) removes content from // ranges. |
গ্লোবাল ' this এর হ্যান্ডলিং সামঞ্জস্য করুন
রাইনো রানটাইম এটি ব্যবহারকারী স্ক্রিপ্টগুলির জন্য একটি অন্তর্নিহিত বিশেষ কনটেক্সট সংজ্ঞায়িত করে। স্ক্রিপ্ট কোড এই অন্তর্নিহিত কনটেক্সটে চলে, যা প্রকৃত গ্লোবাল ' this থেকে আলাদা। এর মানে হলো, কোডে "গ্লোবাল this "-এর রেফারেন্সগুলি আসলে বিশেষ কনটেক্সটে ইভ্যালুয়েট হয়, যেখানে শুধুমাত্র স্ক্রিপ্টে সংজ্ঞায়িত কোড এবং ভেরিয়েবলগুলো থাকে। বিল্ট-ইন অ্যাপস স্ক্রিপ্ট সার্ভিস এবং ECMAScript অবজেক্টগুলি this এর এই ব্যবহার থেকে বাদ থাকে। এই পরিস্থিতিটি এই জাভাস্ক্রিপ্ট কাঠামোর অনুরূপ ছিল:
// Rhino runtime // Apps Script built-in services defined here, in the actual global context. var SpreadsheetApp = { openById: function() { ... } getActive: function() { ... } // etc. }; function() { // Implicit special context; all your code goes here. If the global this // is referenced in your code, it only contains elements from this context. // Any global variables you defined. var x = 42; // Your script functions. function myFunction() { ... } // End of your code. }(); |
V8-এ, অন্তর্নিহিত বিশেষ কনটেক্সটটি সরিয়ে দেওয়া হয়েছে। স্ক্রিপ্টে সংজ্ঞায়িত গ্লোবাল ভেরিয়েবল এবং ফাংশনগুলিকে বিল্ট-ইন অ্যাপস স্ক্রিপ্ট পরিষেবা এবং Math ও Date মতো ECMAScript বিল্ট-ইনগুলির পাশে গ্লোবাল কনটেক্সটে রাখা হয়।
আপনার স্ক্রিপ্টটি V8-এ স্থানান্তরিত করার সময়, গ্লোবাল প্রেক্ষাপটে this এর ব্যবহার সংক্রান্ত আপনার কোডের প্রত্যাশাগুলো পরীক্ষা করুন এবং প্রয়োজন অনুযায়ী সামঞ্জস্য করুন। বেশিরভাগ ক্ষেত্রে, পার্থক্যগুলো কেবল তখনই স্পষ্ট হয় যখন আপনার কোড গ্লোবাল this অবজেক্টের কী (key) বা প্রপার্টির নামগুলো পরীক্ষা করে দেখে:
// Rhino runtime var myGlobal = 5; function myFunction() { // Only logs [myFunction, myGlobal]; console.log(Object.keys(this)); // Only logs [myFunction, myGlobal]; console.log( Object.getOwnPropertyNames(this)); } | // V8 runtime var myGlobal = 5; function myFunction() { // Logs an array that includes the names // of Apps Script services // (CalendarApp, GmailApp, etc.) in // addition to myFunction and myGlobal. console.log(Object.keys(this)); // Logs an array that includes the same // values as above, and also includes // ECMAScript built-ins like Math, Date, // and Object. console.log( Object.getOwnPropertyNames(this)); } |
লাইব্রেরিতে instanceof এর পরিচালনা সামঞ্জস্য করুন
অন্য প্রজেক্টের কোনো ফাংশনে প্যারামিটার হিসেবে পাস করা অবজেক্টের ওপর লাইব্রেরিতে instanceof ব্যবহার করলে ফলস নেগেটিভ ফলাফল আসতে পারে। V8 রানটাইমে, একটি প্রজেক্ট এবং এর লাইব্রেরিগুলো ভিন্ন ভিন্ন এক্সিকিউশন কনটেক্সটে চলে এবং একারণে সেগুলোর গ্লোবাল ও প্রোটোটাইপ চেইনও ভিন্ন হয়।
এটি কেবল তখনই ঘটে, যদি আপনার লাইব্রেরি এমন কোনো অবজেক্টের উপর instanceof ব্যবহার করে যা আপনার প্রোজেক্টে তৈরি করা হয়নি। আপনার প্রোজেক্টে তৈরি করা কোনো অবজেক্টের উপর এটি ব্যবহার করলে, তা আপনার প্রোজেক্টের একই বা ভিন্ন কোনো স্ক্রিপ্টে হোক না কেন, প্রত্যাশিতভাবেই কাজ করার কথা।
যদি V8-এ চলমান কোনো প্রজেক্ট আপনার স্ক্রিপ্টকে লাইব্রেরি হিসেবে ব্যবহার করে, তবে পরীক্ষা করে দেখুন আপনার স্ক্রিপ্টটি অন্য কোনো প্রজেক্ট থেকে পাঠানো প্যারামিটারে instanceof ব্যবহার করছে কি না। আপনার ব্যবহারের ক্ষেত্র অনুযায়ী instanceof এর ব্যবহার পরিবর্তন করুন এবং অন্যান্য সম্ভাব্য বিকল্প ব্যবহার করুন।
a instanceof b এর একটি বিকল্প হতে পারে a এর কনস্ট্রাক্টর ব্যবহার করা, বিশেষত যখন পুরো প্রোটোটাইপ চেইন খোঁজার প্রয়োজন হয় না এবং শুধু কনস্ট্রাক্টরটি পরীক্ষা করলেই চলে। ব্যবহারবিধি: a.constructor.name == "b"
প্রজেক্ট A এবং প্রজেক্ট B বিবেচনা করুন, যেখানে প্রজেক্ট A, প্রজেক্ট B-কে একটি লাইব্রেরি হিসেবে ব্যবহার করে।
//Rhino runtime //Project A function caller() { var date = new Date(); // Returns true return B.callee(date); } //Project B function callee(date) { // Returns true return(date instanceof Date); } | //V8 runtime //Project A function caller() { var date = new Date(); // Returns false return B.callee(date); } //Project B function callee(date) { // Incorrectly returns false return(date instanceof Date); // Consider using return (date.constructor.name == // “Date”) instead. // return (date.constructor.name == “Date”) -> Returns // true } |
আরেকটি বিকল্প হতে পারে মূল প্রজেক্টে instanceof চেক করার জন্য একটি ফাংশন যুক্ত করা এবং লাইব্রেরির কোনো ফাংশন কল করার সময় অন্যান্য প্যারামিটারের সাথে সেই ফাংশনটিও পাস করা। এরপর পাস করা ফাংশনটি লাইব্রেরির ভেতরে instanceof চেক করার জন্য ব্যবহার করা যাবে।
//V8 runtime //Project A function caller() { var date = new Date(); // Returns True return B.callee(date, date => date instanceof Date); } //Project B function callee(date, checkInstanceOf) { // Returns True return checkInstanceOf(date); } |
লাইব্রেরিতে অ-শেয়ারকৃত রিসোর্স স্থানান্তরের বিষয়টি সমন্বয় করুন।
V8 রানটাইমে মূল স্ক্রিপ্ট থেকে কোনো লাইব্রেরিতে একটি নন-শেয়ার্ড রিসোর্স পাঠানোর প্রক্রিয়াটি ভিন্নভাবে কাজ করে।
রাইনো রানটাইমে, কোনো নন-শেয়ার্ড রিসোর্স পাস করলে তা কাজ করে না। এর পরিবর্তে লাইব্রেরিটি তার নিজস্ব রিসোর্স ব্যবহার করে।
V8 রানটাইমে, লাইব্রেরিতে একটি নন-শেয়ার্ড রিসোর্স পাস করলে তা কাজ করে। লাইব্রেরিটি পাস করা নন-শেয়ার্ড রিসোর্সটি ব্যবহার করে।
নন-শেয়ার্ড রিসোর্সকে ফাংশন প্যারামিটার হিসেবে পাস করবেন না। নন-শেয়ার্ড রিসোর্স সবসময় সেই একই স্ক্রিপ্টে ডিক্লেয়ার করুন যেখানে সেগুলি ব্যবহৃত হয়।
প্রজেক্ট A এবং প্রজেক্ট B বিবেচনা করুন, যেখানে প্রজেক্ট A, প্রজেক্ট B-কে একটি লাইব্রেরি হিসেবে ব্যবহার করে। এই উদাহরণে, PropertiesService হলো একটি নন-শেয়ার্ড রিসোর্স।
// Rhino runtime // Project A function testPassingNonSharedProperties() { PropertiesService.getScriptProperties() .setProperty('project', 'Project-A'); B.setScriptProperties(); // Prints: Project-B Logger.log(B.getScriptProperties( PropertiesService, 'project')); } | // V8 runtime // Project A function testPassingNonSharedProperties() { PropertiesService.getScriptProperties() .setProperty('project', 'Project-A'); B.setScriptProperties(); // Prints: Project-A Logger.log(B.getScriptProperties( PropertiesService, 'project')); } |
V8 রানটাইমে JDBC সুপারিশসমূহ
V8 রানটাইমের সাথে আমরা JDBC সার্ভিসে নতুন ফিচার যুক্ত করেছি।
ব্যাচ অপারেশনের জন্য executeBatch ব্যবহার করুন
ব্যাচ ডাটাবেস অপারেশন সম্পাদন করতে executeBatch(params) অপারেশন ব্যবহার করুন।
নিম্নলিখিত উদাহরণে দেখানো হয়েছে কিভাবে ব্যাচিং ব্যবহার করে একটি ডাটাবেসে একাধিক সারি সন্নিবেশ করানো যায়:
এই হলো রাইনো রানটাইম (পুরানো পদ্ধতি):
var conn = Jdbc.getCloudSqlConnection("jdbc:google:mysql://..."); var stmt = conn.prepareStatement("INSERT INTO employees (name, age) VALUES (?, ?)"); var params = [["John Doe", 30], ["John Smith", 25]]; for (var i = 0; i < params.length; i++) { stmt.setString(1, params[i][0]); stmt.setInt(2, params[i][1]); stmt.execute(); }
এই হলো V8 রানটাইম (নতুন পদ্ধতি):
var conn = Jdbc.getCloudSqlConnection("jdbc:google:mysql://..."); var stmt = conn.prepareStatement("INSERT INTO employees (name, age) VALUES (?, ?)"); var params = [["John Doe", 30], ["John Smith", 25]]; stmt.executeBatch(params);
ফলাফল সেট আনতে getRows ব্যবহার করুন
একবারে রেজাল্ট সেটের ডেটা পেতে getRows(queryString) ব্যবহার করুন। queryString টি JdbcResultSet এর গেটার মেথডগুলোর কমা-বিভক্ত কল নিয়ে গঠিত, উদাহরণস্বরূপ: "getString(1), getDouble('price'), getDate(3, 'UTC')" । সমর্থিত মেথডগুলোর মধ্যে কলাম ডেটা পড়ার জন্য ব্যবহৃত সমস্ত গেটার মেথড অন্তর্ভুক্ত, যেমন, getHoldability , getMetaData ইত্যাদি সমর্থিত নয়। আর্গুমেন্টগুলো পূর্ণসংখ্যা কলাম ইনডেক্স (১-ভিত্তিক) অথবা সিঙ্গেল বা ডাবল কোটেড স্ট্রিং কলাম লেবেল হতে পারে।
নিম্নলিখিত উদাহরণটি দেখায় কিভাবে ফলাফল সেট থেকে সারিগুলি আনতে হয়:
এই হলো রাইনো রানটাইম (পুরানো পদ্ধতি):
var conn = Jdbc.getCloudSqlConnection("jdbc:google:mysql://..."); var stmt = conn.createStatement(); var rs = stmt.executeQuery("SELECT name, age FROM employees"); while (rs.next()) { Logger.log(rs.getString('name') + ", " + rs.getInt('age')); }
এই হলো V8 রানটাইম (নতুন পদ্ধতি):
var conn = Jdbc.getCloudSqlConnection("jdbc:google:mysql://..."); var stmt = conn.createStatement(); var rs = stmt.executeQuery("SELECT name, age FROM employees"); var rows = rs.getRows("getString('name'), getInt('age')"); for (var i = 0; i < rows.length; i++) { Logger.log(rows[i][0] + ", " + rows[i][1]); }
স্বতন্ত্র স্ক্রিপ্টগুলিতে অ্যাক্সেস আপডেট করুন
V8 রানটাইমে চলমান স্বতন্ত্র স্ক্রিপ্টগুলোর ট্রিগার সঠিকভাবে কাজ করার জন্য, ব্যবহারকারীদেরকে স্ক্রিপ্টটিতে অন্তত দেখার অ্যাক্সেস (view access) প্রদান করতে হবে।