Makale Özeti

Bu makalemizde, Dynamic Language Runtime ile sağlanan birlikte çalışabilirliği(statik ve dinamik diller arasında) inceleyeceğiz. C# kodu içerisinden IronPython kodlarını nasıl çalıştırabileceğimizi göreceğiz.

Makale

    .NET Framework 4.0 ile birlikte gelen DLR(Dynamic Language Runtime) ,dinamik dillerin(Ruby, Python, Javascript vb.) .NET üzerinde kullanılabilirlik ve birlikte çalışabilirliğini amaçlamaktadır. Bunun yanısıra, yeni bir tip olarak karşımıza çıkan dynamic; C# ve VB gibi statik dillere dinamik dillerde olan bazı yetenekleri de kazandırmaktadır. Böylelikle statik diller ile IronRuby, IronPython vb. dinamik diller arasında DLR üzerinden etkileşim kurulabilmektedir.

    Örneğin C# içerisinden;

  • Script içerisindeki sınıflardan nesneler oluşturabilmek,
  • Script içerisindeki metotları çağırabilmek,
  • Metinsel ifadeleri çalıştırabilmek

    gibi işlemler daha da kolaylaşmaktadır.

    Bu makalemizde C# ve dinamik diller arasındaki bu etkileşimin nasıl gerçekleştirebileceğinden bahsetmeye çalışacağız. Bu etkileşimi göstermek için dinamik dil olarak  IronPython kullanacağız. Öncelikle , IronPython için gerekli olan kurulum dosyalarını http://www.codeplex.com/wikipage?ProjectName=IronPython adresinden indirmemiz gerekmektedir. Kurulum işleminde dosyalar varsayılan olarak “Program Files” altına kopyalanacaktır. Kurulum tamamlandıktan sonra Visual Studio ile yeni bir proje oluşturalım ve IronPython ile birlikte gelen gerekli dll referanslarını ekleyelim. Şu anda IronPython kurulumunun ana klasöründe yer alan IronPython.dll ve Microsoft.Scripting.dll kütüphanelerine referans eklemeniz yeterli olacaktır. Ayrıca .NET kütüphanelerinden Microsoft.CSharp.dll dosyasına da referans ekliyoruz. Artık konumuza dönmeye ve örneklerimizi çalıştırmaya hazırız.

    dynamic tipi, C# ve VB gibi dillere dinamik dillerde olan bazı özellikleri kazandırmış olsa da, gerçek dinamik dillerde olan bazı işlemler gerçekleştirilememektedir. Şimdi aşağıdaki örneği inceleyelim:

dynamic exp = "6+3"; 

    exp isimli dynamic bir tip yarattık ve değer olarak “6+3” şeklinde bir ifade verdik. C# dinamik özelliklere sahip olmuş olsa da bu ifadeyi basit bir metin olarak görecektir. Oysa; IronPython ve IronRuby gibi gerçek dinamik dillerin bu tip ifadeleri çalıştırabilmesi mümkündür. Bunu C# ile doğrudan çalıştıramasak da, dinamik bir dil üzerinden daha kolay işletebiliriz. DLR sayesinde, dinamik dillerin C# içerisinden çağrılabilmesi kolaylaşmaktadır. Bahsettiğimiz konuyu bir örnek üzerinden gösterelim:

using System;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;

namespace IronPythonSample {
    class Program {
        static void Main(string[] args) {
            string exp = "6+3";

            ScriptEngine engine = Python.CreateEngine();
            dynamic result = engine.Execute(exp);

            Console.WriteLine("Toplama Sonucu: {0}", result);

            Console.ReadLine();
        }
    }
}

    Öncelikle, Python için bir ScriptEngine oluşturuyoruz. Ardından bu engine yardımı ile ifademizi Python üzerinden çalıştırıyoruz. Kodu çalıştırdığımızda “6+3” işleminin sonucunu doğru bir şekilde hesaplanmış olduğunu görebilirsiniz.

    exp

    İlk örneğimizde basit bir metinsel ifadenin Python üzerinden nasıl işletilebileceğini gördük. Bu işlemleri gerçekleştirirken değişkenleri de kullanabilmemiz mümkündür. C# ve script arasında değişkenleri aktarabilir ve elde edilen sonuçları yine değişkenler üzerinden alabiliriz. Konuyu yeni bir örnek üzerinden inceleyelim:

string ortalama = "ort = (final*0.6)+(vize*0.4)";

ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();

scope.SetVariable("final", 85);
scope.SetVariable("vize", 60);

ScriptSource source = engine.CreateScriptSourceFromString(ortalama, SourceCodeKind.SingleStatement);
source.Execute(scope);

dynamic ort = scope.GetVariable("ort");

Console.WriteLine("Yıl sonu ortalaması : {0}",ort);
Console.ReadLine();

    Örneğimizde; final ve vize notundan yıl sonu ortalamasını hesaplayan bir ifade oluşturduk. Görüldüğü gibi, ifademiz içerisinde final, vize ve ort olmak üzere 3 değişken kullanılıyor. İfademizi çalıştırmadan önce, vize ve final değişkenlerinin değerlerini sağlamamız gerekecektir. Bunun için bir ScriptScope nesnesi oluşturuyor ve gerekli değişkenler için değerlerimizi ekliyoruz. İfademizi çalıştırdıktan sonra ise oluşan ort değişkeninin değerini okuyoruz.  Artık sonucu görebiliriz:

exp2

 

    Her iki örneğimizde de matematiksel ifadeleri çalıştırdık. Şimdi ise bir Python sınıfı içerisinde tanımlanmış metodu C# üzerinden çalıştırmayı deneyelim. Öncelikle bir Python sınıfına ihtiyacımız olacaktır:

class MyClass:
	def __init__(self):
		pass
	def add(self, a, b):
		return a + b

    Kod örneğinde de görüldüğü gibi MyClass isimli basit bir sınıf oluşturduk ve toplama yapacak bir metot ekledik. Bu script’i, “MyClass.py” isimli bir dosya olarak kaydediyoruz. Artık script’i C# içerisinden kullanabiliriz:

using System;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
using Microsoft.Scripting;

namespace IronPythonSample {
    class Program {
        static void Main(string[] args) {

            ScriptEngine engine = Python.CreateEngine();
            ScriptSource source = engine.CreateScriptSourceFromFile("MyClass.py");
            ScriptScope scope = engine.CreateScope();

            source.Execute(scope);
            dynamic myClassType = scope.GetVariable("MyClass");
            dynamic myClass = myClassType();

            dynamic result = myClass.add(3, 5);

            Console.WriteLine("Sonuç : {0}", result);
            Console.ReadLine();
        }
    }
}

    Kod örneğinde de görüldüğü gibi, script dosyamızı kullanarak bir ScriptSource nesnesi oluşturuyoruz. Ardından, ScriptScope aracılığıyla script içerisindeki MyClass tipine ulaşıyoruz. MyClass sınıfından yeni bir örnek oluşturdukdan sonra add fonksiyonunu bir C#  fonksiyonu gibi kullanıyoruz. Sonuç, işlemin başarılı olduğunu göstermektedir:

exp3

 

SONUÇ

    Örneklerde de görüldüğü gibi DLR, statik dillere dinamik yetenekler katmasının yanısıra, statik ve dinamik diller arasındaki birlikte çalışabilirliği de kolaylaştırmaktadır. Metinsel ifadelerin çalıştırılması ile ilgili örneklerde basit matematiksel ifadeler kullanmaya çalıştık. Bu örneklerden yola çıkarak basit bir hesap makinesi yazılımı da geliştirebilirsiniz. Kullanıcının ekrana girdiği ifadeyi herhangi bir ayrıştırmaya gerek kalmadan Python üzerinden kolaylıkla çalıştırabilirsiniz. Dikkat etmeniz gereken nokta bu ifadelerin C# dilinin değil, Pyhton programlama dilinin kurallarına uygun olmasıdır.

Cemil ABİŞ
http://www.cemilabis.com
http://twitter.com/cemilabis