Wann wäre die Verwendung einer Skriptsprache in einem größeren Programm sinnvoll?


70

Ich habe von mehreren Situationen gehört, in denen Leute JavaScript oder Python (oder etwas anderes) in einem in C # geschriebenen Programm verwenden. Wann wäre es besser, eine Sprache wie JavaScript zu verwenden, um etwas in einem C # -Programm zu tun, als es nur in C # zu tun?


1
Warum hat jemand diese Frage abgelehnt? IMHO ist es eine gute Frage.
KK.

28
Es ist sehr nützlich, um absurd komplexe Software-Teile zu erstellen, für deren Wartung teure Berater erforderlich sind, insbesondere wenn die Skriptsprache schrecklich ist.
Whatsisname

2
Ich habe keine "Antwort", aber der Pragmatic Programmer hat ein Kapitel darüber (# 12 - Domain Languages). Könnte Ihnen einen Einblick geben.
Craige

1
Es gibt einige gute Antworten auf eine ähnliche Frage auf Game Development: gamedev.stackexchange.com/questions/2913/...
celion

6
Manchmal ist es sogar besser, ein großes System in einer Skriptsprache zu haben - es heißt " Unix-Methode ". Mit einer winzigen Skriptebene können Sie zahlreiche unterschiedliche Subsysteme zusammenkleben. Diese Architektur ist bekanntermaßen sehr robust und skalierbar.
SK-logic

Antworten:


66

Wenn Sie ein Verhalten haben, das Sie nicht neu kompilieren müssen, um es zu ändern. Genau aus diesem Grund verwenden so viele Spiele Lua als Skriptsprache.


42
Außerdem können Benutzer Funktionen selbst hinzufügen. Sie haben es irgendwie impliziert, aber ich denke, es ist wichtig genug, um mehr betont zu werden.

2
Auch Sandboxen. Schauen Sie sich die Integration von Python in Blender an.
Meawoppl

@meawoppl ... oder um einem Programm Funktionen hinzuzufügen. Schauen Sie sich IDAs Integration von Python (genannt IDAPython) an
Cole Johnson

Warum machen Sie es nicht so, dass Sie nur eine Bibliothek neu kompilieren müssen (z. B. mit bestimmten Spielelogikkomponenten)?
Den

Wenn Sie sich andere Tools wie AutoCAD, Sparx Enterprise Architect und MS Word ansehen, müssen Sie diese nicht neu kompilieren, um sie in C # zu skripten.
Pete Kirkham

28

Diese Technik kann verwendet werden, um Kernlogik zu implementieren, die leicht zwischen verschiedenen Sprachumgebungen portierbar ist. Zum Beispiel habe ich einen Taschenrechnersimulator, in dem die gesamte interne Taschenrechnerlogik in 100% JavaScript implementiert ist. Der Benutzeroberflächencode ist natürlich für jede Plattform unterschiedlich:

  • Webbrowser (JavaScript)
  • iOS (Ziel-C)
  • Windows (C ++ mit Qt)
  • Mac OS X (C ++ mit Qt)
  • Java Swing (Java)

Mit dieser Anordnung ist es viel einfacher, Versionen meines Programms für verschiedene Betriebsumgebungen zu erstellen und insbesondere auf dem neuesten Stand zu halten.


18

Im Allgemeinen gibt es zwei Situationen, in denen Sie dieses Muster anwenden würden:

  1. Dies wird intern verwendet, um die Qualität der eingebetteten Sprache zu verbessern.
  2. Dies wird verwendet, um externe Programmierbarkeit bereitzustellen.

Im Inneren

  • In der Regel wird die eingebettete Sprache interpretiert, sodass Änderungen schnell vorgenommen und getestet werden können, ohne dass eine Neukompilierung erforderlich ist.
  • Die eingebettete Sprache ist möglicherweise aussagekräftiger als die Sprache, in der Ihre Kernanwendung geschrieben ist, was wiederum eine schnellere Entwicklung ermöglicht.
  • Die Sprache passt möglicherweise besser zu einer bestimmten Domäne als eine Allzwecksprache.
  • Die Sprache wird von internen Benutzern verwendet, die eine "einfachere" Programmiersprache / -umgebung benötigen. Kurze Programme werden von Leuten geschrieben, die keine Softwareentwickler sind und eine relativ einfache Syntax / API verwenden.

Ein Beispiel hierfür ist Lua, das in Adobe Lightroom verwendet wird.

Was wir also mit Lua tun, ist im Wesentlichen die gesamte Anwendungslogik, von der Ausführung der Benutzeroberfläche bis zur Verwaltung dessen, was wir tatsächlich in der Datenbank tun. Nahezu jeder Code in der App, der als Treffen von Entscheidungen oder Implementieren von Funktionen beschrieben werden kann, ist in Lua enthalten, bis Sie zur unformatierten Verarbeitung in C ++ gelangen. ( Mark Hamburg Interview: Adobe Photoshop Lightroom )

Äußerlich

  • Ermöglichen Sie Benutzern, das Verhalten Ihrer Anwendung zu erweitern, ohne spezielle Tools und / oder Bibliotheken zu benötigen und / oder auf Ihren Quellcode zuzugreifen.
  • Stellen Sie diesen Benutzern eine gut definierte API und eine Sandkastenumgebung zur Verfügung. Dies kann auch in der Sprache der Anwendung erfolgen, die Einbettung eines Interpreters kann dies jedoch erleichtern.

IBM hat Skriptsprachen in ihrem Mainframe-Betriebssystem VM-CMS sehr erfolgreich eingesetzt . EXEC , EXEC / 2 und später Rexx wurden systemübergreifend sowohl intern als auch extern eingesetzt. Verschiedene Anwendungen (z. B. XEDIT ) waren mit denselben Sprachen skriptfähig, und interne Anwendungen / Dienstprogramme (z. B. E-Mail) wurden in der Skriptsprache geschrieben und nutzten die enge Integration mit dem Betriebssystem und anderen Tools. Kunden haben viele skriptbasierte Tools und Anwendungen erstellt und freigegeben. DEC lieferte auch DCL . Später unterstützte Microsoft VBscript als Skriptsprache in den meisten Anwendungen und neuerdings auch in PowerShell(auch MS / DOS- Batchdateien ). Unix-Shells haben auch Scripting .

Der heutige Trend scheint darin zu bestehen, APIs in irgendeiner Weise verfügbar zu machen und die Wahl der Skriptsprache Benutzern zu überlassen, die unterschiedliche Bindungen oder andere Möglichkeiten für den Zugriff auf die API verwenden können.


9

Beispiele aus der Praxis wären:

  • Die meisten Webbrowser, die eingebettetes JavaScript unterstützen.

  • Microsoft Office Suite - Excel Word usw. Alle unterstützen eingebettete VBA-Skripte.

  • Viele Netzwerkrouter enthalten Skript-APIs in einer Vielzahl von Sprachen TCL, Perl, Lua.

Viele eingebettete Geräte werden mit einem sehr kleinen Satz von C-Kernfunktionen implementiert, die mit einer Skriptsprache wie Lua zusammengefügt werden. Sie verfügen also über eine Reihe kleiner, schneller C-Funktionen, die mit der Hardware und dem Großteil der Steuerlogik in einer flexiblen, einfach zu ändernden Skriptsprache interagieren.


@ antony.trupe. Der häufig verwendete Name für ECMAscript - en.wikipedia.org/wiki/ECMAScript
James Anderson

4

Manchmal ist Scripting in eine Anwendung eingebettet, weil es die Host-Anwendung durch andere Entwickler erweitern kann. Um ein möglichst breites Spektrum an Programmiersprachenkenntnissen zu erfassen, können vom Host mehrere Skriptsprachen unterstützt werden. In der JVM können Sie beispielsweise eine ganze Reihe von JSR-223-kompatiblen Sprachen wie Python, Ruby, JavaScript usw. einbetten .

Ein weiterer Grund, der nicht bereits erwähnt wurde, ist, dass die eingebettete Sprache ein oder mehrere herausragende Merkmale aufweist, die die Hostsprache nicht leicht duplizieren kann. Ein Beispiel hierfür wäre die Parse-Funktionalität oder die mühelose Erstellung von DSL (domänenspezifische Sprache / Dialekt), die in einer Sprache wie Rebol zu finden ist.


3

Es gibt eine interessante Möglichkeit, eine Skriptsprache in einer Anwendung zu verwenden, die von den anderen noch nicht erwähnt wurde.

Wenn Ihre Host-Sprache eine umfangreiche, reflektierende Laufzeit hat, ist es oft nützlich, eine einfache Sprache mit REPL in Ihre Anwendungen einzubetten, sie an einen Socket anzuschließen und ihr Zugriff auf das gesamte System zu gewähren.

Es kann für ein interaktives Debugging (und es ist natürlich viel leistungsfähiger als Ihr gewöhnlicher Debugger), Hot-Code-Patches, verschiedene Überwachungszwecke und sogar für Hintertüren (wenn Sie nichts Gutes im Sinn haben) verwendet werden.


Natürlich viel leistungsfähiger als Ihr üblicher Debugger? Inwiefern? Wie kann eine "einfache externe Skriptsprache" ohne fundierte Kenntnisse der Redewendungen, des Speichermodells, des Objektmodells, der grundlegenden Datentypen usw. Ihrer Hostsprache nützliche Funktionen bereitstellen, die ein für die Arbeit mit der Sprache entwickelter Debugger nicht bieten kann?
Mason Wheeler

@MasonWheeler, können Sie den Code mit einem normalen Debugger austauschen? Können Sie beliebig komplexe programmierbare Abfragen zum Zustand Ihrer Laufzeit durchführen? Können Sie komplizierte kontrollierte Experimente durchführen? Und Sie gehen zu Unrecht davon aus, dass eine Skriptsprache keine "intrinsischen Kenntnisse der Redewendungen der Host-Sprache besitzt, ...". Wenn sowohl Host- als auch Skriptsprache auf derselben VM ausgeführt werden (.NET, JVM, V8, was auch immer), haben Sie in Ihrer Skriptsprache uneingeschränkten Zugriff auf alle Eingeweide.
SK-logic

1

Meine spezielle Situation, wenn ich in einer Hauptanwendung eine interpretierte Skriptsprache verwende:

Es gibt ein externes Gerät, das mehrere Funktionen ausführt. Messungen, Kontrolle, Anzeigen. Es ist selbst ziemlich "doof" und erfordert eine präzise Steuerung, die Schritt für Schritt viele Wartezustände und Ad-hoc-Entscheidungen auf der Seite des Steuerungsmechanismus umfasst.

Verschiedene Funktionen des Geräts werden an verschiedenen Stellen der Hauptanwendung zu unterschiedlichen Zeiten benötigt, oft nach Bedarf. Die Haupt-App erlaubt keine Wartezustände als solche, alles muss mit Zustandsautomaten erfolgen.

Wer nun eine Zustandsmaschine geschrieben hat, der weiß, dass das Implementieren eines Wartezustands effektiv mindestens zwei, oft drei oder vier interne Zustände der Maschine ist. Das Implementieren von 20 Wartezuständen für verschiedene Funktionen (und das Warten auf deren Antworten und das entsprechende Reagieren) des externen Geräts wäre eine sehr, sehr frustrierende Erfahrung.

Stattdessen gibt es also Zustände wie "Ausführen einer Nichtwarte-Funktion", "Ausführen einer Blockierfunktion", "Ausführen einer Verzweigungs- / Bedingungs- / Sprungfunktion" in der Zustandsmaschine, möglicherweise insgesamt sechs Zustände. Außerdem gibt es Steuerskripte, deren Ausführung vom Interpreter, der das externe Gerät steuert, geplant und deren Ergebnisse dort abgelegt werden, wo sie benötigt werden.

Zusammenfassend lässt sich sagen, dass die Verwendung einer intern interpretierten Skriptsprache in einem RTOS die Komplexität der Ausführung von Aufgaben, die in Wartezuständen häufig vorkommen (Blockierungsfunktionen), erheblich verringern kann.


1

Aus meiner Erfahrung heraus haben wir einmal eine große Anwendung entwickelt, die den Quellcode einer "alten" Sprache neu schreibt, um Unicode-kompatibel zu sein. Das wurde in C # gemacht. Am Ende habe ich nur die Engine (die ein Datenmodell erstellt und die notwendigen Schritte für den Umschreibevorgang bereitstellt) in C # geschrieben - der "Glue-Code" für die eigentliche Ausführung wird in IronPython erstellt.

Der größte Punkt für das integrierte IronPython: Nehmen wir an, Sie haben ein Big-Data-Modell geladen (etwa eine Stunde Ladezeit). Dann möchten Sie manuell Informationen sammeln und nachschlagen. Dies mit einem Python-Skript von einer interaktiven Konsole aus zu tun, ist weitaus besser als mit dem Debugger durch das Datenmodell zu klicken (und es kann wieder abgespielt werden).


-2

Es gibt einige Gründe.

  • Lernkurve. Praktisch jeder kann in Javascript lernen und schreiben.
  • Sicherheit. Es ist schwierig, den Sicherheitskontext von Skriptcode in C # oder Java zu steuern. Dafür ist Javascript perfekt. Der Skriptautor kann niemals auf die Festplatte oder irgendwo anders zugreifen, wenn er dies nicht zulässt. Die Haupt-Javascript-Engine ist nur ein fortschrittlicher Taschenrechner.
  • Qualität. Sie haben dem Skriptcode eine sehr hohe Grenze gesetzt. "Spaghetti Code" -Stufen sind für Javascript oder C # / Java sehr unterschiedlich. (Was Sie daran hindert, die Tore der Hölle zu öffnen)
  • Geben Sie Sicherheit. C # / Java sind typensichere Umgebungen, die Sie in einer Skriptumgebung meistens nicht bevorzugen. Ausdruck wie "12" + 3 ergibt "123" in Javascript, aber C # / Java wird nicht einmal kompiliert. Drehbuchautoren macht meist nicht mal was "Typ" ist
  • Dynamisch. Jedes Objekt kann eine beliebige Eigenschaft / Methode enthalten und den Typ in der Zeit ändern. Beispielsweise könnte ich der Skriptumgebung ein Proxy-C # -Objekt bereitstellen, das XML-Knoten als Eigenschaften verfügbar macht.
  • Produktivität. Normalerweise ist das Schreiben von Skripten viel einfacher als in C # / Java. Keine Kompilierung oder "Plugin-Registrierung" erforderlich. Sie können den Skriptinhalt direkt in der Anwendung mit sofortigen Ergebnissen bearbeiten.
  • Verwaltung. Für die Verwendung von C # / Java muss ein SDK mit Plug-ins verknüpft sein, das interne Klassen für die Welt verfügbar macht. Diese Plugin-Architektur erfordert die "Abwärtskompatibilität" für alte SDK-Versionen. Diese Architektur zwingt Sie, "virtuelle" Domänenobjekte zu erstellen, die einen internen Anwendungsmechanismus im Domänenkontext bereitstellen. Es ist übersichtlicher und flexibler als das Anzeigen einer API.

3
Damit ist die Frage der Einbettung von Skripten in ein größeres Programm unbeantwortet. Warum sollte sich ein Entwickler beispielsweise dafür entscheiden, Script-Fu zur Gimp hinzuzufügen ? Oder Civ V mit lua modden - warum sollte ein Entwickler einer Anwendung Skripte hinzufügen?

-3

Wann? Zwischen 1948 und 2008 dauerte das Kompilieren und Verknüpfen der ursprünglich kompilierten Sprachen sehr lange. Daher war es üblich, eine Skriptsprache zu erstellen, mit der Benutzer angepasst und konfiguriert werden konnten. Wenn Sie sich den Verlauf von AutoLisp ansehen, lautet die Antwort zunächst AutoCAD mit einer darin enthaltenen Skriptsprache. Dies wurde jedoch eingestellt, um eine skriptfähige Schnittstelle für VBA und dann für .net bereitzustellen.

Mit CLR unterscheidet sich die Aktivierung eines C # -Programms oder eines Lua-Programmaufrufs in einem vorhandenen System nicht wesentlich in den Entwicklungskosten. Die .net-Laufzeitumgebung wird mit den Tools geliefert, die zum Generieren und Kompilieren im laufenden Betrieb benötigt werden.

Sie müssen keine Skriptsprache mehr im größeren Programm haben, sondern müssen das größere Programm den Skriptfunktionen der Laufzeit aussetzen.

In Umgebungen, die keine direkte Codegenerierung und -kompilierung bieten und es als wünschenswert erachtet wird, anstelle einer domänenspezifischen eine allgemeine Automatisierungssprache anzubieten, erhalten Sie weiterhin Lua- oder Python-Skripte. Bei Tools mit COM-Schnittstelle ist diese Skriptsprache C # oder VB.net (MS Office, Sparx Enterprise Architect). Eine Skriptsprache für ein Programm zu haben, das in einer Sprache geschrieben ist, die selbst einfach genug ist, um eine Skriptsprache zu sein, ist daher unnötig.


Bei einer Google-Suche nach XNA-Spielen mit Lua-Skript werden keine Ergebnisse angezeigt.
user16764

@ user16764 und eine Google-Suche nach Fahrrädern aus Baiser kommen auf sechs Millionen.
Pete Kirkham
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.