Ruby-Like "times" method #ruby #csharp #linq #vb #cpp

Before I noticed how many other people had blogged about this same thing, I wrote an implementation of a "times" (integer extension) method -- the kind you'd find when coding in Ruby that is passed a block of code that it executes (n) times.


Consider the following (in Ruby):

#####################################
# prints:
#   Ruby was here
#   Ruby was here

2.times {
   printf("Ruby was here\n")
}

#####################################
# prints:
#   Ruby was here 0
#   Ruby was here 1

2.times {|i|
   printf("Ruby was here %d\n", i)
}


The closest to this I got in C# was:

public static void DoTest1()
{
   /******************************************************\
    * This technique is the actual goal of this exercise
   \******************************************************/
   2.times(DoWriteLine);   // <-GOAL!
   2.times(DoWriteLineAndNum);
   // or
   2.times(i => Console.WriteLine("CSharp was here"));
   2.times(i => Console.WriteLine("CSharp was here: " + i));
}



The C# class I created (with two extension methods) looks like this: 
 

using System;
using System.Linq;

namespace RubyLike
{
   public static class CRubyLike
   {
     
      /// <summary>
      /// Performs an action i number of times
      /// </summary>
      /// <param name="i">number of times to repeat</param>
      /// <param name="action">action to be repeated</param>
      public static void times(this int i, Action action)
      {
         Enumerable.Range(0, i).ToList().ForEach(n => action());
      }

      /// <summary>
      /// Performs an action i number of times passing the
      /// repeat target as a parameter.
      /// Allowing: 5.times(n => Console.Write("hey"));
      /// </summary>
      /// <param name="i">number of times to repeat</param>
      /// <param name="action">action to be repeated</param>
      public static void times(this int i, Action<int> action)
      {
         int iCount=0;
         Enumerable.Range(0, i).ToList().ForEach(n => action(iCount++));
      }
   }
}

 


 

Here is the C++ Example

// TestRubyLike_CPP.h
#pragma once

using
namespace System;
using namespace RubyLike;

namespace TestRubyLike_CPP {

       public ref class CTestRubyLike_CPP
       {
       private:
              static void DoWriteLine(void)
                     {Console::WriteLine("C++ was here");}
             
              static void DoWriteLine(int i)
                     {Console::WriteLine("C++ was here "+ i.ToString());}
                    
       public:
              static void DoTest(void)
              {
                     CRubyLike::times(2, gcnew Action(DoWriteLine));
                     CRubyLike::times(2, gcnew Action<int>(DoWriteLine));
                     CRubyLike::times(2, gcnew Action(Console::WriteLine));//blank/blank
                     CRubyLike::times(2, gcnew Action<int>(Console::WriteLine));//0/1
              }
       };
}



Here is the VB Example:

Imports System
Imports RubyLike

Public Class CTestRubyLike_VB
   Private Shared Sub DoWriteLine()
      Console.WriteLine("VB was here")
   End Sub

   Private Shared Sub DoWriteLine(ByVal i As Integer)
      Console.WriteLine("VB was here: " & i)
   End Sub

   Public Shared Sub DoTest1()
      Dim iVal As Integer = 2
      iVal.times(New Action(AddressOf DoWriteLine))
      iVal.times(New Action(Of Integer)(AddressOf DoWriteLine))
      iVal.times(New Action(AddressOf Console.WriteLine)) 'blank/blank
      iVal.times(New Action(Of Integer)(AddressOf Console.WriteLine)) '2/2
   End Sub

   Public Shared Sub DoTest2()
      CRubyLike.times(2, New Action(AddressOf DoWriteLine))
      CRubyLike.times(2, New Action(Of Integer)(AddressOf DoWriteLine))
      CRubyLike.times(2, New Action(AddressOf Console.WriteLine)) 'blank/blank
      CRubyLike.times(2, New Action(Of Integer)(AddressOf Console.WriteLine)) '2/2
   End Sub
End
Class



Here is the C# Example:


using System;
using RubyLike;

namespace TestRubyLike_CS
{
   public static class CTestRubyLike_CS
   {
      private static void DoWriteLine()
      {
         Console.WriteLine("CSharp was here");
      }

      private static void DoWriteLineAndNum(int i)
      {
         Console.WriteLine("CSharp was here: " + i);
      }

      public static void DoTest1()
      {
         /******************************************************\
          * This technique is the actual goal of this exercise
         \******************************************************/
         2.times(DoWriteLine);   // <-GOAL!
         2.times(DoWriteLineAndNum);

         // or
         2.times(i => Console.WriteLine("CSharp was here"));
         2.times(i => Console.WriteLine("CSharp was here: " + i));
      }

      public static void DoTest2()
      {
         CRubyLike.times(2, DoWriteLine);
         CRubyLike.times(2, DoWriteLineAndNum);
         CRubyLike.times(2, (Action)Console.WriteLine);//blank/blank
         CRubyLike.times(2, (Action<int>)Console.WriteLine);//2/2
      }
   }
}


Here is a calling program for these (in C#)

using System;
using TestRubyLike_CS;
using TestRubyLike_CPP;
using TestRubyLike_VB;

namespace TestRubyLike 
{
   public static class CTestRubyLike
   {
      static void Main(string[] args)
      {
         ///////////////////////////////
         // Make calls on extension methods
         Console.WriteLine("C# Example 1: ---------------------");
         CTestRubyLike_CS.DoTest1();

         // or
         ///////////////////////////////////
         // Make calls on static methods
         Console.WriteLine("C# Example 2: ---------------------");
         CTestRubyLike_CS.DoTest2();
        
         ///////////////////////
         // Make calls from C++
         Console.WriteLine("C++ Example: ----------------------");
         CTestRubyLike_CPP.DoTest();

         /////////////////////
         // Make calls from VB
         Console.WriteLine("VB Example 1: ---------------------");
         CTestRubyLike_VB.DoTest1();

         //or
         Console.WriteLine("VB Example 2: ---------------------");
         CTestRubyLike_VB.DoTest2();
      }
   }
}


And, of course, the output:


TestRubyLikeOutput Picture

 

posted @ Wednesday, March 3, 2010 2:07 PM
Print

Comments on this entry:

No comments posted yet.

Your comment:



(not displayed)

 
 
 
 

Live Comment Preview: