My team is currently creating an API that will interact with our core Ruby API.
The new API is for the public as the Ruby API is our private API. We want to be able to compile this new API into a PHP, Java, Python, etc., client libraries when we are ready to release.
Are there any gems, or other ways to write this new API so we can compile it into different client libraries?
There are several ways to think about exposing an API these days. If we're talking about creating a library in the sense of something compiled into other applications, that takes us down one path. If we're talking about providing, effectively, command line functionality callable from other contexts as system calls, that's another story. More broadly is the API is more of a service, like REST, that's different. I'll assume one of the first two.
There are several tools that will create a binary package for platforms. Look at ruby-tioolbox.com for some examples. None of these are compiling true executable code (as far as I know) but mainly provide an executable version of ruby with your code and dependencies packaged up. Perhaps the API appears callable as a system library (DLL for Windows, SO for UNIXy).
But either way, I would think you're dealing with ruby and your code loading and running as a separate process on each call. There's a library like this (not in Ruby) called ImageMagick, with a wrapper for ruby calls called MiniMagick that might be a pointer to the kind of pattern you're looking for.
If you want to run ruby and your app as a service, there are several tools for this -- this helps address the overhead of loading a process each time, and built into Ruby 1.9 is a Process class that daemonizes ruby, although presumably only on Unix. Check this SO answer
The best answer is probably that ruby, like other similar languages (e.g. Python) are really not designed to be low-level system libraries. There are likely many ways of accomplishing what you want in a given environment (notably Linux) ... but as far as I know nothing that really exposes executable codepoints to all languages.
Related
A community member would like to utilise Python to integrate aspects of their application with NEAR. Would it be possible to build an application on NEAR using Python? Can the NEAR API be used with Python?
With NEAR you build on 2 fronts:
"Inside": Contracts (to write code that runs on-chain and changes state in the system)
"Outside": API (to create dApps that communicate with NEAR)
Contracts
We currently support two languages:
Rust (near-sdk-rs)
and AssemblyScript (near-sdk-as)
You can find more examples of contracts written in both of these languages in our NEAR Examples GitHub org, many of which are running live on near.dev
In the future we will support any language that we (or our community) decides to enable from a pretty long list where “enable” means building out the sdk like near-sdk-rs and near-sdk-as linked above.
API
We currently have a JSON RPC API that you can use from any language (including Python) as well as a convenient wrapper for JavaScript developers called near-api-js. Again, we (or our community) can decide to build more convenient wrappers for any other language we want to support, including Go, Java, C#, Python, Ruby, etc
As a side note, if someone in the community is interested in Python specifically, there’s a ton of it currently being used to do things like run tests (nearcore pytest), manage builds (nearcore scripts) and deploy nodes (nearup) as well as simulate some of the on-chain stuff like the Runtime
I use py-near
https://pypi.org/project/py-near/
built-in transactions with FT
fully asynchronous library
good documentation
built-in transfers NEAR/Ft by SMS
multiple RPC node support
Current status of truffleruby says:
TruffleRuby is progressing fast but is currently probably not ready for you to try running your full Ruby application on. Support for critical C extensions such as OpenSSL and Nokogiri is missing.
Why does truffleruby need C extensions? It's built on GraalVM which is built on top of the JVM, it is in fact a fork of JRuby:
TruffleRuby is a fork of JRuby, combining it with code from the Rubinius project, and also containing code from the standard implementation of Ruby, MRI.
Can't they use JRuby world gems instead of depending on their C variants?
EDIT link to the issue on github
Running C extensions is hard because the C extension API is just the entire internals of MRI exposed as a header file. You aren't programming against a clean API - you're programming against all the implementation details and internal design decisions of MRI.
JRuby's Java extensions have exactly the same problem! The JRuby Java extension API is just the entire internals of JRuby, and you aren't programming against an API, instead you're programming against all the implementations details and design decisions of JRuby.
We plan to eventually tackle both problems in the same way - which is to add another level of abstraction over the C or Java code using an interpreter which we can intercept and redirect when required, so that it believes it is running against MRI or JRuby internals, but really we redirect these to our internals.
We think C extensions are more important, so we're tackling those first. We haven't really started on Java extensions yet, but we have started the underlying interpreter for Java that we'll use.
This video explains all
https://youtu.be/YLtjkP9bD_U?t=1562
You have already gotten a good answer by the project lead himself, but I want to offer a different point of view:
Why does truffleruby need C extensions?
It doesn't need them. But they do exist and there is code out there which uses them, and it would sure be nice to be able to run that code.
What are the code tutorial shells called that are used on various websites such as codecademy, codeschool, mongo db, try ruby etc.
Is there a service for building and maintaining these things? Or is it something you build yourself?
I found ShellInABox but it doesn't seem exactly like the only one people are using?
These are colloquially known as "web REPLs" (a term meaning "Read/Eval/Print Loop").
They can be distinguished by unrestricted ones used for debugging by describing them as "sandboxed". There is not a single, universal toolkit used to build these, though you may find repl.it (which uses a number of interpreters compiled to javascript to run client-side REPLs for numerous languages) interesting.
What are the major differences between the execution of Ruby C bindings vs. Ruby wrapper for system calls?
To my question into context, I am looking into incorporating Git version control functionality heavily into a Ruby on Rails application. In approaching this task I do not understand the how to think about the execution pipeline of a Ruby program which incorporates a library implemented with Ruby C bindings such as yajl-ruby vs. a Ruby wrapper for system calls such as the git Ruby Gem.
Bindings interface directly with the library's API, while wrappers use system calls to invoke the end-user application from the command line.
Wrappers are similar to UNIX pipes – programs have no knowledge about each other's internals and communicate through a textual interface. Loose coupling comes with a price, though. System calls are expensive operations and will dramatically slow down your application.
This is why bindings are great. Since they use the library's programming interface, the overhead is significantly reduced. GitHub had its own git wrapper, and speed was issue that led them to implement git in Ruby.
They did it themselves because it is kind of hard to make bindings for git. It wasn't designed to be used as a library. It's really awkward to call its functions directly since it calls die() on pretty much any error.
The demand for a proper git library led to the development of libgit2. It even comes with Ruby bindings! Since you want to integrate git functionality with your application, you should check it out.
On Windows there a few libraries that allow you to intercept calls to DLLs:
http://www.codeproject.com/kb/system/hooksys.aspx
Is it possible to do this on Mac OS? If so, how is it done?
The answer depends on whether you want to do this in your own application or systemwide. In your own application, it's pretty easy; the dynamic linker provides features such as DYLD_INSERT_LIBRARIES. If you're doing this for debugging/instrumentation purposes, also check out DTrace.
You can replace Objective-C method implementations with method swizzling, e.g. JRSwizzle or Apple's method_exchangeImplementations (10.5+).
If you want to modify library behavior systemwide, you're going to need to load into other processes' address spaces.
Two loading mechanisms originally designed for other purposes (input managers and scripting additions) are commonly abused for this purpose, but I wouldn't really recommend them.
mach_inject/mach_override are an open-source set of libraries for loading code and replacing function implementations, respectively; however, you're responsible for writing your own application which uses the libraries. (Also, take a look at this answer; you need special permissions to inject code into other processes.)
Please keep in mind that application patching/code injection for non-debugging purposes is strongly discouraged by Apple and some Mac users (and developers) are extremely critical of the practice. Much of this criticism is poorly informed, but there have been a number of legitimately poorly written "plug-ins" (particularly those which patch Safari) that have been implicated in application crashes and problems. Code defensively.
(Disclaimer: I am the author of a (free) APE module and an application which uses mach_inject.)