Our life around REPL – Read–Eval–Print Loop

Whenever I see my niece so comfortable with iPhone, Mac, Advance Toys; I usually wonder almost similar feeling our parents must have pondered about us. But what is the biggest disadvantage of being part of GEN X. What? We have best things in the world but the irony is that we don’t enjoy or embrace the inventions/creations done by our forefathers generation. For us TV, Radio, Telephone, Mobile, Desktop was little obvious, now for next generation iPhone, iPad, Smartphone, DSLR, Laptops, Tablets et al are very obvious. Its clearly visible our parents struggle with our generation widgets and I have now started to struggle with next-generation gadgets.

You must be thinking what is it had to do with REPL. During college days, I started coding in C, bit of Java (to clear job interviews incase required), then majorly on PHP, RUBY, PYTHON, JAVASCRIPT, BASH. The moment I started coding on these languages, which are derived from their forefathers C & Lisp, I sensed a sheer bliss while working on them and started promoting them in peer group as soon as I realized the language is always available and it was obvious not to look back at C, C++, Java and many others. We can easily compare it to Gramophone, cassettes, VCR , VCP, Landline but these inventions were the foundation of where we stand today in our life or in programming world.

I was not clear about the term REPL when I started working on these languages and thought of it as a jargon of programming world. Recently, wrote a smallest code on ruby and a REPL was created. This is when I realized the power of REPL and thought to read about their forefathers. Let’s first have a sneak-peek into that smallest piece of ruby repl code.REPL

#!/usr/bin/env ruby
loop {p eval gets }

 

Now read this piece of code in reverse order, READ (gets), EVAL, PRINT (p), LOOP. Save this file as repl.rb and run as`ruby repl.rb`

─$ ruby repl.rb 1 ↵
"akshay Gupta".upcase
"AKSHAY GUPTA"
1+2*3
7

Congratulations, now you understand REPL and underlying fact of  language is always available i.e. no real distinction between read-time, compile-time and run-time. Now, when I start working on any new language, it’s easier to pick up if it’s REPL based and I truly thank Mr. John McCarthy father of Artificial Intelligence, creator of LISP (where lies the roots of REPL) for his immense contribution in the field of computer science, AI, programming languages and so many programming paradigm. If i’m not wrong, he is also the inventor of if-then-else conditional construct and we take these for granted now.

Running code at read-time lets users reprogram; running code at compile-time is the basis of macros; compiling at runtime is the basis of Lisp’s use as an extension language in programs like Emacs; and reading at runtime enables programs to communicate using expressions.

There have been two really clean, consistent models of programming so far: the C model and the Lisp model. As computers have grown more powerful, the new languages being developed have been moving steadily toward the Lisp model. A popular recipe for new programming languages in the past 20 years has been to take the C model of computing and add some parts taken from the Lisp model, like runtime typing and garbage collection.

repl-loop

It’s equally important to look forward and innovate in coming time and respect, embrace the efforts of our remarkable forefathers. To read and practice different languages that support REPL please follow the below links. I primarily depend heavily upon irb and PRY.

In our everyday life we do nothing more than READ (consume knowledge), EVAL ( between right and wrong), PRINT (discuss around), LOOP (day everyday) i.e. REPL 🙂

 

Rails: Calling Stored Procedure and read OUT variables in Sequel

Very recently stumbled upon a situation, where I need to call a Oracle DB Stored Procedure and also need to read the OUT variables in one of our Ruby on Rails application or in simple words read the output after calling stored procedure in one of our Rails application.

To add to our dismay, it’s not ActiveRecord connection but we were using Sequel library. Sequel do support the Oracle library and it’s very silimar to AR ORM and thanks to this wonderful gem that works out-of-the-box. But it’s not straight forward to call Stored PROC and read the OUT variables and there is next to no documentation to process OUT variables from our stored PROC

DB specific SQL can be executed using “execute” method and almost all the DB adapters provide this method. But question remains the same how to read the OUT variables and I have never called a Stored Procedure ever in my life. It seems an interesting problem to solve and answer may be hidden somewhere in the code but no documentation.

Let’s try to read the OUT variables in different ways taking one step at a time:

1. Create a sample procedure which takes one integer and one string as input and returns integer multiplied by 2 and UPPERCASE of string

create or replace
PROCEDURE MYPROC 
(
 age IN NUMBER 
, name IN VARCHAR2 
, fathers_age OUT NUMBER 
, capital_name OUT VARCHAR2 
) AS 
BEGIN
 fathers_age := age*2;
 capital_name := UPPER(name);
END MYPROC;

 

2. How to call using SQL and read OUT variables (in SQLDeveloper)

 var age number
 var naam varchar2
 var papa_age number
 var bada_naam varchar2
 exec :age := 20
 exec :naam := 'akshay'
 exec MYPROC (age => :age, name => :naam, fathers_age => :papa_age, capital_name => :bada_naam)
 print papa_age
 print bada_naam

OUTPUT

PAPA_AGE
--
40
BADA_NAAM
------
AKSHAY

 

3. How to call it using ActiveRecord using Ruby OCI8 GEM

cursor = ActiveRecord::Base.connection.raw_connection.parse("BEGIN MYPROC(:age, :name, :fathers_age, :capital_name); END;")
cursor.bind_param(:name, 'akshay')
cursor.bind_param(:age, '20')
cursor.bind_param(:fathers_age, nil, Fixnum)
cursor.bind_param(:capital_name, nil, String, 20)
cursor.exec()
p cursor[:fathers_age], cursor[:capital_name]

OUTPUT

1.8.7 :125 > cursor.exec()
 => 1
1.8.7 :126 > p cursor[:fathers_age], cursor[:capital_name]
40
"AKSHAY"

 

4. How to call it using Sequel Database Toolkit.

require 'sequel'
db = Sequel.connect(:adapter=>'oracle', :host=>'localhost', :database=>'db_name', :user=>'test', :password=>'test')
db.execute("begin MYPROC(:age, :name, :fathers_age, :capital_name); end;", {:arguments => [[20, "integer"], ["akshay", "string"], [nil, "integer"], [nil, "string"]]}) { |cursor| [cursor[3], cursor[4]] }

OUTPUT:

1.8.7 :158 > db.execute("begin MYPROC(:age, :name, :fathers_age, :capital_name); end;", {:arguments => [[20, "integer"], ["akshay", "string"], [nil, "integer"], [nil, "string"]]}) { |cursor| [cursor[3], cursor[4]] }
 => [40, "AKSHAY"]

 

This is important to note, oracle adapter inside sequel uses the Ruby OCI8 gem but the implementation is not straight forward as in the case of ActiveRecord.

To further understand how the variables are bound and how are we reading out the OUT variables, I recommend to read the code written inside the ORACLE adapter of SEQUEL gem.

Hope this bit of information is useful and many thanks to  for such a great sequel gem. Happy Hacking 🙂

 

 

Magical ‘If..then..else’ conditional statement

I believe whole programming world stands on couple of pillars and ‘if..then..else’ (ITE) statement is one of those. Everyone programmer and non-programmer understands ITE conditional statement for sure.

 A typical if..then..else.. statement in Ruby:

 if 1 == 2
   puts "inside if statement"
 else
   puts "inside else statement"
 end
1.9.3p385  > inside else statement
Another example in ruby:
#/bin/ruby
near = "father"
if near == "father"
  puts "I'm studying"
elsif near == "mother"
 puts "I'm playing"
else
 puts "I'm sleeping"
end

1.9.3p385  > I'm studying

Essence is either of two given block is executed i.e. either if block or else block is executed by the code in any language.

Can there be a case/situation when both of these blocks if & else are executed?

…. This is really an unusual question but seriously can this be achieved. Can we challenge the very existence of conditional flow? Are the basics we have learned aren’t true anymore?

Answer lies in situation and yes this can be achieved. Unix fork(2) is the answer and can help if..then..else to behave in this manner.

example magicalif.rb

if f1 = fork
  puts "inside fork"
elsif f2 = fork
  puts "inside second fork"
else
  puts "outside fork"
end

─$ ruby magicalif.rb

inside fork
inside second fork
outside fork

So what has just happened? Condition checks for fork(2), kernel command to create a subprocess of the parent process.  So fork, creates a subprocess called child process similar to parent process (having copy of parent process, file descriptors and sockets etc) and returns a pid (child process) to parent process and nil to child process. Hence, IF block was executed by parent process as it returned pid to parent process and ELSE statement is executed by CHILD process as fork returned nil to child process.

Let’s have a closer look which block is executed by which process (parent or child)

supermagicalif.rb

puts "Master Process: #{Process.pid}"
if f1 = fork
  puts "inside fork"
  puts "Fork PID: #{f1}"
  puts "Process pid: #{Process.pid}"
elsif f2 = fork
  puts "inside second fork"
  puts "Fork PID: #{f2}"
  puts "Process pid: #{Process.pid}"
else
  puts "outside fork"
  puts "Process pid: #{Process.pid}"
end

─$ ruby supermagicalif.rb
Master Process: 21267
inside fork
Fork PID: 21268
Process pid: 21267
inside second fork
Fork PID: 21269
Process pid: 21268
outside fork
Process pid: 21269

This clearly shows IF block is executed by PARENT process, ELSIF block executed by first CHILD process and ELSE block executed by SECOND CHILD process.

Will have a more closer look in fork(2) in next blog where will see it’s usage and how can it be used in our programming. For now, yes it’s possible and now you know MAGICAL IF..THEN..ELSE statement 🙂

RubyMotion Runtime Guide

Object Model

inside-ruby-motion

 

The object model of RubyMotion is based on Objective-C, the underlying language runtime of the iOS and OS X SDK. Objective-C is an object-oriented flavor of C that has been, like Ruby, heavily influenced by the Smalltalk language.

Sharing a common ancestor, the object models of Ruby and Objective-C are conceptually similar. For instance, both languages have the notion of open classes, single inheritance and single dynamic message dispatch.

In RubyMotion, Ruby classes, methods and objects are Objective-C classes, methods and objects respectively. The converse is also true. Objective-C classes, methods and objects are available in Ruby as if they were native.RubyMotion implements the Ruby object model by using the Objective-C runtime, the library that powers the Objective-C language and indirectly, the iOS SDK APIs.

By sharing the same object model infrastructure, Objective-C and RubyMotion APIs can be interchangeable at no additional performance expense.

via RubyMotion Runtime Guide.

Smartphone Native Application using Ruby in 30 min

Building a Smartphone (Android, iPhone, BlackBerry etc) app using ruby

Google Android
iPhone Logo
BlackBerry Logo


RhoMobile Framework


Rhodes

Rhodes is an open source framework to rapidly build NATIVE apps for all major smartphone operating systems (iPhone, Windows Mobile, RIM, Symbian and Android). These are true native device applications (NOT mobile web apps) which work with synchronized local data and take advantage of device capabilities such as GPS, PIM contacts and camera.

Yeah! Its in Ruby 🙂

  • support for ALL smartphones
  • synchronized offline data
  • a Model View Controller (MVC) framework
  • an Object Relational Manager (ORM) to avoid direct SQL coding
  • the mobile Ruby
  • a hosted development service
  • scaffolding to quickly build the app

Setup (Android)

  • gem install rhodes
  • Java JDK latest version is needed for Android. Make sure its installed. Test by typing $javac -version in your terminal
  • Download Android SDK (for linuxMac OSWindows) and extract at a convenient location.
  • Change in your ~/.bash_profile(Mac) and ~/.bashrc(Linux) to add
    export PATH=/path-to-android/tools:$PATH
    export ANDROID_HOME=/path-to-android
  • typing $android in the terminal shall start Android SDK and AVD Manager
  • once ACD manager started install the latest packages under “Available packages”, it will take a while to install
  • Once installed they will list under “Installed Packages”
  • else installation follow these instructions to install Android SDK starter packages, and change the PATH environment variable for sure
  • Download and install Android NDK (Win, Mac OS, Linux) and export your path same as above

Setting up rhodes
Now we need to link our rhodes installation to the SDK and eclipse.
$rhodes-setup
You’ll be prompted with questions – my answers are below:
  • JDK path: /Library/Java/Home
  • Android SDK path: /opt/androidSDK/
  • Android NDK path: /opt/androidNDK/
  • the remainder of the questions related to Windows and Blackberry: (left blank)

HelloWorld Program

rhogen app HelloWorld

cd HelloWorld

rake -T  (will list all the rake tasks for all supported smartphones)

rake run:android (it will build, install and launch the HelloWorld Program)

Of course it will be blank and its just the start. Go to launcher you will be able to see your HelloWorld application with rhodes default icon.

My Contacts

This is fine, but what about ruby and MVC framework? Open your latest HelloWorld in your favorite editor(textmate etc). You will find an “app”, “app=>helpers” folder much like rails “rhoconfig.txt” => configuration settings

$ rhogen model Contact name, email, phone

Generating with model generator:

[ADDED]  app/Contact/index.erb

[ADDED]  app/Contact/edit.erb

[ADDED]  app/Contact/new.erb

[ADDED]  app/Contact/show.erb

[ADDED]  app/Contact/index.bb.erb

[ADDED]  app/Contact/edit.bb.erb

[ADDED]  app/Contact/new.bb.erb

[ADDED]  app/Contact/show.bb.erb

[ADDED]  app/Contact/contact_controller.rb

[ADDED]  app/Contact/contact.rb

[ADDED]  app/test/contact_spec.rb

You can see the controller, model and view files similar to Rails frame work.

Change the

start_path = ‘/app/Contact’ (in rhoconfig.txt)

$ rake run:android

Your application will relaunch and you can click “new” button to add new contacts and edit and delete them. So basic CRUD functionality is available much like rails and ready to go.

I hope you will find this ready to go tutorial very helpful to start of your application on any smartphone using Rhodes framework.

Stay tuned for more!