• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • A Ruby And RPG Conversation

    March 17, 2015 Aaron Bartell

    “Due diligence” and “risk assessment” are phrases that should be running through your head anytime technology decisions are being made where new tooling or ideas are being put into production. The same is true when considering whether the Ruby language has a place in your shop. After all, it is a significant change in direction when introducing a new language to your technology stack.

    What many people don’t know is the adoption of Ruby (and the Rails web framework) can be done in incremental fashion if that is what works best for you. What I mean by that is not only can you make use of your existing DB2 tables, but also your significant investment in RPG code. How? Well, that’s what this article is all about. Let’s dive in.

    The Ruby language has this concept called RubyGems, which is a package manager for ease of distributing and maintaining Ruby code (usually open source). Think of a RubyGem being similar to RPG *SRVPGMs being stored in a *SAVF for distribution to other machines, except all done based on an agreed upon specification that includes tools for downloading, installing, and updating. Or maybe better stated, imagine a world where we had so much open source RPG code that we had to come up with streamlined ways to share it. That’s RubyGems. I will cover RubyGems more thoroughly in a future article.

    Included with PowerRuby is a RubyGem named the xmlservice gem. The xmlservice gem is a native-to-Ruby way of communicating with the platform-and-language-agnostic XMLSERVICE open source project developed in IBM Rochester by IBM’er Tony Cairns. The xmlservice gem can be used to communicate with nearly any resource on IBM i including DB2 tables, data queues, and most notably an RPG program or service program.

    Below we have a very simple RPG program that receives in two parameters passed by reference, alters their values, and then returns. Note, this is the new 100 percent free-form RPG introduced in V7.1 TR7. If you are like me you might still be adjusting. I didn’t want to be told I wasn’t modern with RPG so I am trying to change my ways.

    --- MYLIB/PGM1 ---
     dcl-pr pgm1 extpgm; 
       char1 char(1);
       dec1 packed(7:4);
     end-pr;
     dcl-pi pgm1;
       char1 char(1);
       dec1 packed(7:4);
     end-pi;
    
     char1 = 'C';
     dec1 = 321.1234;
     return;
    

    Our goal is to invoke PGM1 from Ruby and display the value back to the screen. In my article Testing The Ruby Waters, I introduced the idea of testing Ruby code from irb (interactive Ruby shell) and that’s what we will do here. Below we have the entirety of the Ruby code necessary to invoke the aforementioned RPG program using the xmlservice gem. In this scenario we are making use of the database adapter for communication with the other option being the RESTful adapter (i.e., invoke the RPG program via an HTTP request).

    --- Lines of Ruby code to paste into IRB ---
    require 'active_support'
    require 'active_record'
    require 'ibm_db'
    require 'xmlservice'
    
    ActiveRecord::Base.establish_connection(
      adapter: 'ibm_db', 
      database: '*LOCAL', 
      schema: 'MYLIB', 
      username: 'xxxxx', 
      password: 'xxxxx'
    )
    
    pgm1 = XMLService::I_PGM.new("PGM1", 'MYLIB') <<
           XMLService::I_a.new('mychar1', 1, 'a') <<
           XMLService::I_p.new('mydec1', 7, 4, 11.1111) 
    
    pgm1.call
    
    puts pgm1.response.mychar1
    puts pgm1.response.mydec1
    

    The first four lines are Ruby require statements that are similar to doing /copy in RPG–bringing outside functionality into the program.

    Next we establish the database connection details where a specific library (a.k.a., schema) needs to be specified, though this has no bearing on where the actual RPG program resides most likely because the world of database adapters isn’t used to the concept of storing executable programs inside of what they’d consider a database schema. In short, you will need to supply an existing library for the schema value and also a valid username and password.

    Next we have the configuration of the call to PGM1 in MYLIB by calling XMLService::I_PGM.new, which then uses the left-shift operator (<<) to append the two parameters, mychar1 and mydec1. Note that a default value is also being specified for both parameters, ‘a’ and 11.1111 respectively. You could have instead used variables but I’ve hard-coded for the sake of brevity.

    At this point the variable pgm1 contains all the information it needs to invoke the RPG program. On the next line the call method does the actual invocation of RPG and waits for a response. As mentioned before, this particular scenario we are calling RPG through a DB2 connection, which is effectively a generic stored procedure–very fast.

    The last two puts lines are conveying the resulting variable values to the terminal.

    When you paste the above into an irb session it will have a lot more output conveyed back to you, as shown in this gist. What is a gist you ask? A way to easily share a snippet of code, or logs, or other text; either privately or with the world.

    The above code would be too verbose to use multiple times in an application so it would be better to encapsulate it into something like the following:

    require 'active_support'
    require 'active_record'
    require 'ibm_db'
    require 'xmlservice'
    
    class Pgm1
      attr_accessor :char1, :dec1
      def initialize
        ActiveRecord::Base.establish_connection(
          adapter: 'ibm_db', 
          database: '*LOCAL', 
          schema: 'MYLIB', 
          username: 'xxxxx', 
          password: 'xxxxx'
        )
        @char1 = nil
        @dec1 = nil
      End
      def call(c1, d1)
        pgm1 = XMLService::I_PGM.new("PGM1", 'MYLIB') <<
               XMLService::I_a.new('mychar1', 1, c1) <<
               XMLService::I_p.new('mydec1', 7, 4, d1) 
        pgm1.call
        @char1 = pgm1.response.mychar1
        @dec1 = pgm1.response.mydec1
      End
    end
    

    Then you can more simply invoke it as follows.

    p = Pgm1.new
    p.call('a', 11.1111)
    puts p.char1
    puts p.dec1
    

    Another code refinement would be to place the establish_connection portion in a separate file rather than have it in each Ruby class that represents an RPG program. As you may have guessed, we’ve officially ventured into authoring object-oriented Ruby code without me first explaining it. I did that on purpose because sometimes it’s better to have a full working example and then go back and learn the individual pieces. Here is a good one-pager to learn the object oriented aspects of Ruby.

    That wraps up this installment of Ruby learning. It is worth noting that the XMLSERVICE API is very flexible when compared to its predecessors (i.e., PCML, Java Toolbox) and the simplicity of my example is not a reflection of XMLSERVICE’s capabilities. It should also be noted that XMLSERVICE allows you to create stateful jobs on the server side so you can make subsequent calls and have things be retained (i.e., open data paths, global variables in a service program, etc.). This opens the door for Ruby and XMLSERVICE to be used for RPG unit testing–something I hope to cover in a future article. Stay tuned!

    Aaron Bartell is Director of IBM i Innovation for Krengel Technology, Inc. Aaron facilitates adoption of open source technologies on IBM i through professional services, staff training, speaking engagements, and the authoring of best practices within industry publications and www.litmis.com. With a strong background in RPG application development, Aaron covers topics that enable IBM i shops to embrace today’s leading technologies including Ruby on Rails, Node.js, Git for RPG source change management and RSpec for unit testing RPG. Aaron is a passionate advocate of vibrant technology communities and the corresponding benefits available for today’s modern application developers. Connect with Aaron via email at abartell@krengeltech.com. Aaron lives with his wife and five children in Southern Minnesota. He enjoys the vast amounts of laughter having a young family brings, along with camping and music. He believes there’s no greater purpose than to give of our life and time to help others.

    RELATED STORIES

    Git To GitHub

    Git To It

    Knee-Deep In Ruby Waters

    Testing The Ruby Waters

    Bash Is Not A Shell Game

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags:

    Sponsored by
    WorksRight Software

    Do you need area code information?
    Do you need ZIP Code information?
    Do you need ZIP+4 information?
    Do you need city name information?
    Do you need county information?
    Do you need a nearest dealer locator system?

    We can HELP! We have affordable AS/400 software and data to do all of the above. Whether you need a simple city name retrieval system or a sophisticated CASS postal coding system, we have it for you!

    The ZIP/CITY system is based on 5-digit ZIP Codes. You can retrieve city names, state names, county names, area codes, time zones, latitude, longitude, and more just by knowing the ZIP Code. We supply information on all the latest area code changes. A nearest dealer locator function is also included. ZIP/CITY includes software, data, monthly updates, and unlimited support. The cost is $495 per year.

    PER/ZIP4 is a sophisticated CASS certified postal coding system for assigning ZIP Codes, ZIP+4, carrier route, and delivery point codes. PER/ZIP4 also provides county names and FIPS codes. PER/ZIP4 can be used interactively, in batch, and with callable programs. PER/ZIP4 includes software, data, monthly updates, and unlimited support. The cost is $3,900 for the first year, and $1,950 for renewal.

    Just call us and we’ll arrange for 30 days FREE use of either ZIP/CITY or PER/ZIP4.

    WorksRight Software, Inc.
    Phone: 601-856-8337
    Fax: 601-856-9432
    Email: software@worksright.com
    Website: www.worksright.com

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Sponsored Links

    COMMON:  2015 Annual Meeting & Expo, April 26 - 29, at the Disneyland® Resort in Anaheim, California
    Profound Logic Software:  Extend & Future-proof RPG Apps with PHP. March 25 Webinar!
    COMMON:  2015 Annual Meeting & Expo, April 26 - 29, at the Disneyland® Resort in Anaheim, California

    Storagepipe Takes Aim At IBM i Tape Backup And Recovery IBM Patches BIND and OpenSSL Flaws in IBM i

    Leave a Reply Cancel reply

Volume 15, Number 05 -- March 17, 2015
THIS ISSUE SPONSORED BY:

ProData Computer Services
HelpSystems
WorksRight Software

Table of Contents

  • Death To Decimal Data Errors!
  • SQL Joins With Tree Structures: An Oracular Point Of View
  • A Ruby And RPG Conversation

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • Public Preview For Watson Code Assistant for i Available Soon
  • COMMON Youth Movement Continues at POWERUp 2025
  • IBM Preserves Memory Investments Across Power10 And Power11
  • Eradani Uses AI For New EDI And API Service
  • Picking Apart IBM’s $150 Billion In US Manufacturing And R&D
  • FAX/400 And CICS For i Are Dead. What Will IBM Kill Next?
  • Fresche Overhauls X-Analysis With Web UI, AI Smarts
  • Is It Time To Add The Rust Programming Language To IBM i?
  • Is IBM Going To Raise Prices On Power10 Expert Care?
  • IBM i PTF Guide, Volume 27, Number 20

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2025 IT Jungle