B4J Library jRuby

This library is similar to my nashorn and python libs, but allows you to use ruby from b4j.

The library has the same format as the other two
it needs #AdditionJars: path/to/your/jRuby.jar
B4X:
' in globals
Dim jr As jInvokeRuby
...
jr.InitInvocable("some/path/to/your/ruby/file.rb")
'or
jr.InitInvocable(aStringContainingTheScript)
...
jr.Invoke("theFunction",array(the,list,of,parameters)) ie def test(a,b,c,d)
or
jr.Invoke("theFunction",null) ' no args  ie def test()

If you want to call a sub in your b4j app - you need to add some code to both the ruby script and b4j app
B4X:
' for b4j app
...
Dim s As String = Me
s = s.Replace("class ","")
jr.Invoke("setB4J",Array(s)) ' this sets a global variable in the ruby script
                                           'call it before you call functions in the b4j app
...

' for the ruby script at start of script
require "java"
@b4j = ""
...
' and add this function somewhere in the script
def setB4J(a)
@b4j = JavaUtilities.get_proxy_class(a)
end

' now you can call public subs in current class with
def test2()
@b4j._externalcall("hello from jruby") ' calls Sub externalCall(s As String)
                                                        ' note the _ before the lowercase name
end
'or access global variables
def test3()
@b4j._yourglobalvariable = "hello" ' etc
end

Ignore the rubyLibs function at present, it does nothing.

You need to download jRuby ( I am using ver 9.1.8.0)
 

Attachments

  • jInvokeRubyLib.zip
    3.7 KB · Views: 273
Last edited:

Daestrum

Expert
Licensed User
Longtime User
One other thing that's fun having jRuby installed on your pc is you can fully automate the creation of a web server.

Not one like jetty where you have to create all the pages, but one that

a) Generates all the pages for the website.
b) Creates the back-end database - complete with all the required html pages to add, delete and view the records.

Worth having a play to learn Ruby (Especially as current rate for dev's is circa £50k - £80k)

I will post example code to show creation process, when I have commented it bit so it makes sense.

Using B4J to front end the process makes it far better than using command prompt windows.
 

Daestrum

Expert
Licensed User
Longtime User
The server creation code (Obviously you will need to amend the paths to suit your setup)
B4X:
'Non-UI application (console / server application)
#Region Project Attributes 
 #CommandLineArgs:
 #MergeLibraries: True
#End Region
Sub Process_Globals
 Dim sh As Shell
End Sub
Sub AppStart (Args() As String)
 doBuild
 doBuildDB
 doRake
 doServer
 StartMessageLoop
End Sub
Sub doBuild
 ' This is the first step - it will create a directory tree under the appname "test_app" in current directory
 ' in debug thats /Objects/test_app
 ' Uses lots of Wait For's to get each stage to run in correct order
 sh.Initialize("sh","jruby",Array("-S","rails","new","test_app"))
 sh.RunWithOutputEvents(-1)
 wait For (sh) sh_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
 EditGem
 Wait For EditGem_complete
 CallSubDelayed(Me,"doBuild_complete")
End Sub
Sub doBuild_complete
 Log("Build complete")
End Sub
' this is needed as the default installation uses wrong driver so we edit the file between stages
Sub EditGem
 Log("in edit gem")
 Dim s As String = File.ReadString("C:/b4j Problems/jRuby/Objects/test_app/","gemfile")
 s = s.Replace("gem 'activerecord-jdbcsqlite3-adapter'","gem 'activerecord-jdbcmysql-adapter', '~> 5.0.pre1'")
 File.WriteString("C:/b4j Problems/jRuby/Objects/test_app/","gemfile",s)
 CallSubDelayed(Me,"EditGem_complete")
End Sub
Sub EditGem_complete
 Log("Gem Edit complete")
End Sub
' This is second stage - it builds the data base for us
Sub doBuildDB
 Log("in build db")
 Wait For doBuild_complete
 ' on the next line 'People' is the database - and field definitions follow
 ' this generates the pages for our server
 ' this is the command sh.Initialize("sh","jruby",Array("-S","rails", "g", "scaffold",
 ' the rest is the definitions
 sh.Initialize("sh","jruby",Array("-S","rails", "g", "scaffold", "People", "name:string", "age:integer", "address:text"))
 sh.WorkingDirectory = "C:/b4j Problems/jRuby/Objects/test_app/"
 sh.RunWithOutputEvents(-1)
 wait For (sh) sh_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
 CallSubDelayed(Me,"doBuildDB_complete")
End Sub
Sub doBuildDB_complete
 Log("BuildDB complete")
End Sub
' this is stage 3 - where it really creates the database for us
Sub doRake
 Wait For doBuildDB_complete
 sh.Initialize("sh","jruby",Array("-S","rake","db:migrate")) ' Always this command no edit required
 sh.WorkingDirectory = "C:/b4j Problems/jRuby/Objects/test_app/"
 sh.RunWithOutputEvents(-1)
 wait For (sh) sh_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
 EditRake
 Wait For EditRake_complete
 CallSubDelayed(Me,"doRake_complete")
End Sub
Sub doRake_complete
 Log("Rake complete")
End Sub
' Again you need to edit the routes.rb file to tell it the main page of the server
Sub EditRake
 Log("in edit rake")
 Dim s As String = File.ReadString("C:/b4j Problems/jRuby/Objects/test_app/config","routes.rb")
 ' we tell it we want people#index as the default page
 s = s.Replace("resources :people","resources :people"&CRLF&"root 'people#index'")
 File.WriteString("C:/b4j Problems/jRuby/Objects/test_app/config","routes.rb",s)
 CallSubDelayed(Me,"EditRake_complete")
End Sub
Sub EditRake_complete
 Log("Rake complete")
End Sub
' last stage - start the server - its ctrl-c to stop it.
' we could call stop,essage loopand let b4j exit just leaving server running.
Sub doServer
 Wait For doRake_complete
 Log("starting server")
 sh.Initialize("sh","jruby",Array("-S","rails","s"))
 sh.WorkingDirectory = "C:/b4j Problems/jRuby/Objects/test_app/"
 sh.RunWithOutputEvents(-1)
End Sub
' --------------------------------
' just subs for the shell routines
' --------------------------------
Sub sh_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
 If Success Then 
 Log("done : "& StdOut)
 Else
 Log("<<ERROR>> : "&StdErr)
 End If
End Sub
Sub sh_StdOut (Buffer() As Byte, Length As Int)
 Log("Info >>"&BytesToString(Buffer,0,Length,"utf8"))
End Sub
Sub sh_StdErr (Buffer() As Byte, Length As Int)
 Log("Error >>"&BytesToString(Buffer,0,Length,"utf8"))
End Sub
'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
 Return True
End Sub

Have fun :)
 
Top