CSC/ECE 517 Fall 2012/1w41 as: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 80: Line 80:
In Ruby, any object will have a class of which it is an instance (the class of the object can be found by calling the method class on it). Ruby has a feature where we can add additional methods to an object. So, when this is done, a new anonymous class is created which acts as an intermediate between the object and its actual class. This intermediate class or proxy class is called as a singleton class.
In Ruby, any object will have a class of which it is an instance (the class of the object can be found by calling the method class on it). Ruby has a feature where we can add additional methods to an object. So, when this is done, a new anonymous class is created which acts as an intermediate between the object and its actual class. This intermediate class or proxy class is called as a singleton class.
We can consider the above example of array and finding the sum for this as well.
We can consider the above example of array and finding the sum for this as well.
==Method aliasing==
Method aliasing is a technique used in Ruby to implement the concept of meta-programming. The technique that allows us to give aliases or new names to already existing variables, operators and methods is called as method aliasing. It can also be used to wrap an existing method effectively by intercepting any calls and injecting the desired behavior. Here the new reference or the aliasing name may not be a local, instance, constant, or class variable if we are aliasing a variable.
Using this method or technique we can perform method over riding efficiently and thereby change the behavior of an object or a class. There are two keywords in Ruby which provide this method aliasing. They are alias and alias_method. The following is the syntax for both these keywords:
      alias        :new  :old
      alias_method    :new, :old
Generally we use alias to give a second name to a method or variable of a class, whereas we use alias_method when we want to assign second name to a method in a Module. So basically, alias keyword takes two arguments as we can see in the syntax. The first argument is the new name or the second name and second argument is the old name or the original name. Let us look at an example that illustrates this technique. Consider the following example:
    class Array
    def sum
        inject {|a, x| a+x }
    end
    alias  :newsum:sum
    end
    a = Array.new([1, 2, 3, 4])
    a.newsum  #=> 10
In this example, we are defining a new method called sum and then aliasing that method with a new name called newsum in the class Array. Now we can call this method with its alias name as above and still the method will be invoked.
This is how method aliasing can be implementing. We can notice here that, this technique can be used to add new methods and alias those methods for a given class. In this manner we can also change the behavior of the class. Also, we can call the aliasing name of a method inside another method thereby implementing method over riding concept. Consider the following example to illustrate this:
        class A
          def method1
            puts ”This is the main method”
          end
          alias :method2 :method1
          def method1
              puts “This is not main method"
              method2
          end
        end
        a = A.new()
        a.method1
        => This is not main method
        => This is main method
So, in this manner method over riding is done using method aliasing. We can thus say that method aliasing can be used to implement the concept of meta-programming.

Revision as of 22:18, 3 October 2012

Introduction

In this page, the concept of meta-programming is discussed. We first give the definition of meta-programming, along with a brief description. Next, we give an overview of the concept of meta-program in general i.e., its evolution and implementation in various languages is discussed. We then focus on the languages in which Meta -programming is prevalent namely Ruby, Java, C, C++ and Python. We then follow it up with the advantages and disadvantages of the same before concluding.

Definition

Meta-programming is the discipline of writing programs that represent and manipulate other programs or themselves. An established example of meta-program is a compiler. We can also define a meta-program as a program which generates code and writing such programs is called meta-programming. This allows programmers to get more work done in the same amount of time as they would take to write all the code manually, or it gives programs greater flexibility to efficiently handle new situations without recompilation. The ability of a programming language to be its own meta-language is called reflection or reflexivity. This reflection ability is a feature that is very valuable to facilitate meta-programming.

Evolution of Meta-programming

Meta-programming was first introduced in Lisp. In Lisp, instead of just programming towards the language, we usually build the language up to our program. This is where the meta-programming comes into picture. For meta-programming purpose, Lisp provides macros as a standard facility to write code that will be directly be read and compiled by the system at run time.

For Meta programming in C-language,one of the popular examples is the Lex/Yacc system for generation of parsers and lexical scanners. That is, it reads an input stream specifying the lexical analyzer and outputs source code implementing the lexer in C.

For Meta programming in C++, it is done with C++ templates i.e., we define the program’s content by writing code that generates it. The code is generally written in between question marks.

Similar programs exist for Java and C#. The general idea, however, is that such an approach can be used anywhere we have a formal specification for which we know how to generate code.

Prolog, a generic purpose programming language, which uses the same data structures as the meta-programming and also provides simple clause expansions, is generally used for meta-programming.

How Meta-programming works

Meta-programming usually works in one of three ways. The first way is to expose the internals of the run-time engine to the programming code through application programming interfaces (APIs).

The second approach is dynamic execution of expressions that contain programming commands, often composed from strings, but can also be from other methods using arguments and/or context. Thus, "programs can write programs."

The third way is to step outside the language entirely. General purpose program transformation systems, which accept language descriptions and can carry out arbitrary transformations on those languages, are direct implementations of general meta-programming. This allows meta-programming to be applied to virtually any target language without regard to whether that target language has any meta-programming abilities of its own.

Uses of Meta-programming

Let us look at some of the uses of meta-programming:


1)The major use of meta-programming is that it pre-generates the code at run-time. For example, if we are writing an application and we want a quick lookup table containing keys and values associated with the keys, we can have the program build the table at startup during runtime.


2) It is the key ingredient for Domain Specific Languages. That is we use meta-programming to encapsulate domain-specific knowledge.


3) Using meta-programming we can easily reduce the cost and time of development for a system by one order of magnitude, while improving the overall quality of the resulting code.

Meta programming in Ruby

Here we discuss about the implementation of meta-programming in a programming language called Ruby. We will also discuss about various techniques which help in implementing meta-programming. Ruby is an object-oriented and dynamic language. Ruby is also reflexive i.e., Ruby program can observe and modify its own structure and behavior at runtime. Also in Ruby, code is nothing but data and data is nothing but code. All these features of Ruby make it implement one of its most powerful features called meta-programming efficiently. In Ruby, with this meta-programming feature, we can write code that manipulates language constructs like instance variables, classes and modules at runtime. In Ruby, the classes (both standard classes and the classes created by us) are never closed i.e., we can always add extra methods to an existing class. All we need to do is open the class to which we want to add additional methods and then define the method we want to add. For instance, consider the following example:

  a = [1, 2, 3, 4]

Here ‘a’ is an array and if we want to find the sum of all the elements of the array, we need to open the Array class and add the method to calculate the sum of the array elements.

  class Array
     def sum
      inject{|a,x| a+x}
     end
  end

We can now call method product for the array.

      a.sum
      => 10

In Ruby, we can show as if there were two methods with same name. With this property, we can implement the concept of meta-programming efficiently in Ruby. Suppose, we have a class called Rectangle and it has an initialize method. Here, we can now instantiate this Rectangle by two ways. That is, either by passing in the coordinates of its corners or by passing in any of its corner along with the length and width of the corner. So, in this manner, even though there is only one initialize method, we can act as if there were two.

  # The Rectangle constructor accepts arguments in either
  # of the following forms:
  class Rectangle
     def initialize(*args)
        if args.size < 2  || args.size > 3
           puts 'Sorry wrong number of arguments passed. This method takes either 2 or 3 arguments.'  
        else
           puts 'Correct number of arguments passed!!!'
           if args.size == 2
              puts 'Two arguments'
           else
              puts 'Three arguments'
           end
        end
      end
  end
  Rectangle.new([10, 23], 4, 10)
  #=> Correct number of arguements passed!!!
  #=> Three arguements 
  Rectangle.new([10, 23], [14, 13])
  #=> Correct number of arguements passed!!!
  #=> Two arguements

Singleton classes

Singleton classes are one of the major properties of Ruby which make implementation of meta-programming efficient. Singleton class also called as meta-class or anonymous class is a class that acts as a proxy to the objects of a class. In Ruby, any object will have a class of which it is an instance (the class of the object can be found by calling the method class on it). Ruby has a feature where we can add additional methods to an object. So, when this is done, a new anonymous class is created which acts as an intermediate between the object and its actual class. This intermediate class or proxy class is called as a singleton class. We can consider the above example of array and finding the sum for this as well.

Method aliasing

Method aliasing is a technique used in Ruby to implement the concept of meta-programming. The technique that allows us to give aliases or new names to already existing variables, operators and methods is called as method aliasing. It can also be used to wrap an existing method effectively by intercepting any calls and injecting the desired behavior. Here the new reference or the aliasing name may not be a local, instance, constant, or class variable if we are aliasing a variable. Using this method or technique we can perform method over riding efficiently and thereby change the behavior of an object or a class. There are two keywords in Ruby which provide this method aliasing. They are alias and alias_method. The following is the syntax for both these keywords:

      alias        	:new  :old
      alias_method     :new, :old

Generally we use alias to give a second name to a method or variable of a class, whereas we use alias_method when we want to assign second name to a method in a Module. So basically, alias keyword takes two arguments as we can see in the syntax. The first argument is the new name or the second name and second argument is the old name or the original name. Let us look at an example that illustrates this technique. Consider the following example:

   class Array
    def sum
        inject {|a, x| a+x }
    end
    alias  :newsum:sum
   end
   a = Array.new([1, 2, 3, 4])
   a.newsum   #=> 10

In this example, we are defining a new method called sum and then aliasing that method with a new name called newsum in the class Array. Now we can call this method with its alias name as above and still the method will be invoked. This is how method aliasing can be implementing. We can notice here that, this technique can be used to add new methods and alias those methods for a given class. In this manner we can also change the behavior of the class. Also, we can call the aliasing name of a method inside another method thereby implementing method over riding concept. Consider the following example to illustrate this:

        class A
         def method1
            puts ”This is the main method”
          end
          alias :method2 :method1
          def method1
             puts “This is not main method"
             method2
          end
        end
        a = A.new()
        a.method1
        => This is not main method
        => This is main method	

So, in this manner method over riding is done using method aliasing. We can thus say that method aliasing can be used to implement the concept of meta-programming.