GithubHelp home page GithubHelp logo

rubyinline's Introduction

= Ruby Inline

rdoc :: http://docs.seattlerb.org/RubyInline/
home :: http://www.zenspider.com/ZSS/Products/RubyInline/
code :: https://github.com/seattlerb/rubyinline

== DESCRIPTION:

Inline allows you to write foreign code within your ruby code. It
automatically determines if the code in question has changed and
builds it only when necessary. The extensions are then automatically
loaded into the class/module that defines it.

You can even write extra builders that will allow you to write inlined
code in any language. Use Inline::C as a template and look at
Module#inline for the required API.

== PACKAGING:

To package your binaries into a gem, use hoe's INLINE and
FORCE_PLATFORM env vars.

Example:

  rake package INLINE=1

or:

  rake package INLINE=1 FORCE_PLATFORM=mswin32

See hoe for more details.

== FEATURES/PROBLEMS:

* Quick and easy inlining of your C or C++ code embedded in your ruby script.
* Extendable to work with other languages.
* Automatic conversion between ruby and C basic types
  * char, unsigned, unsigned int, char *, int, long, unsigned long
* inline_c_raw exists for when the automatic conversion isn't sufficient.
* Only recompiles if the inlined code has changed.
* Pretends to be secure.
* Only requires standard ruby libraries, nothing extra to download.

== SYNOPSIS:

  require "inline"
  class MyTest
    inline do |builder|
      builder.c "
        long factorial(int max) {
          int i=max, result=1;
          while (i >= 2) { result *= i--; }
          return result;
        }"
    end
  end
  t = MyTest.new()
  factorial_5 = t.factorial(5)

== SYNOPSIS (C++):

  require 'inline'
  class MyTest
    inline(:C) do |builder|
      builder.include '<iostream>'
      builder.add_compile_flags '-x c++', '-lstdc++'
      builder.c '
        void hello(int i) {
          while (i-- > 0) {
            std::cout << "hello" << std::endl;
          }
        }'
    end
  end
  t = MyTest.new()
  t.hello(3)

== (PSEUDO)BENCHMARKS:

  > make bench

  Running native
  Type = Native   , Iter = 1000000, T = 28.70058100 sec, 0.00002870 sec / iter
  Running primer - preloads the compiler and stuff
  With full builds
  Type = Inline C , Iter = 1000000, T = 7.55118600 sec, 0.00000755 sec / iter
  Type = InlineRaw, Iter = 1000000, T = 7.54488300 sec, 0.00000754 sec / iter
  Type = Alias    , Iter = 1000000, T = 7.53243100 sec, 0.00000753 sec / iter
  Without builds
  Type = Inline C , Iter = 1000000, T = 7.59543300 sec, 0.00000760 sec / iter
  Type = InlineRaw, Iter = 1000000, T = 7.54097200 sec, 0.00000754 sec / iter
  Type = Alias    , Iter = 1000000, T = 7.53654000 sec, 0.00000754 sec / iter

== PROFILING STRATEGY:

0) Always keep a log of your progress and changes.
1) Run code with 'time' and large dataset.
2) Run code with '-rprofile' and smaller dataset, large enough to get good #s.
3) Examine profile output and translate 1 bottleneck to C.
4) Run new code with 'time' and large dataset. Repeat 2-3 if unsatisfied.
5) Run final code with 'time' and compare to the first run.

== REQUIREMENTS:

* Ruby - 1.8.2 has been used on FreeBSD 4.6+ and MacOSX.
* POSIX compliant system (ie pretty much any UNIX, or Cygwin on MS platforms).
* A C/C++ compiler (the same one that compiled your ruby interpreter).
* test::unit for running tests ( http://testunit.talbott.ws/ ).

== INSTALL:

* make test  (optional)
* make install

== LICENSE:

(The MIT License)

Copyright (c) Ryan Davis, seattle.rb

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

rubyinline's People

Contributors

drbrain avatar luislavena avatar zenspider avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rubyinline's Issues

Cache isn't selective enough.

I've quickly thrown together the script below; it's probably the most contrary POC example I can build.

The first time I run it it's perfect; it loads the program defined on the command line converts it to C and runs the function created.

The second time it doesn't run the function I ask for; instead it runs the function that I requested the first time. It looks like you're not hashing the C source to get the name of the shared object.

BTW: Moving the body of the code into the prefix successfully works around the problem in this case, but I have to leave a stub bfprog function in the main builder call.

NOTE: On a related note, what do you thing __DATE__ and __TIME__ should do?

#!/usr/bin/ruby
require "inline"
class BFCode
    inline do |builder|

        h = Hash.new{|_, k|
            (k[0] == "+") ? "m[p]+="+k.length.to_s+";\n" :
            (k[0] == "-") ? "m[p]-="+k.length.to_s+";\n" :
            (k[0] == ">") ? "p+="+k.length.to_s+";\n" :
            (k[0] == "<") ? "p-="+k.length.to_s+";\n" :
            (k[0..3] == "[-]+") ? "m[p]="+(k.length-3).to_s+";\n" :
            "#{k}\n" };
        h['[-]'] = "m[p]=0;\n";
        h['>'] = "p+=1;\n";
        h['<'] = "p-=1;\n";
        h['+'] = "m[p]+=1;\n";
        h['-'] = "m[p]-=1;\n";
        h['['] = "while(m[p]!=0){\n";
        h[']'] = "}\n";
        h['.'] = "putchar(m[p]);\n";
        h[','] = "m[p]=getchar();\n";

        bfcode= "void bfprog() {\n" +
                "static unsigned char m[100000]; register int p=0;\n" +
                ARGF.read.
                gsub(/[^\[\]+,-.<>]/,'').
                gsub(/\[\-\]\+*|\++|-+|>+|<+|./,h) +
                "}\n";

        builder.include "<stdio.h>"
        builder.c bfcode
    end
end

BFCode.new().bfprog();

Error inline on rails

I am trying to use inline with rails! I added a method on array class but when I passed my parameters in my action in my controller I got this error

http://pastie.org/2487427

do you know how can I use inline from a outside file and load it in my controller? I didnt find any example on the internet!

thanks

ZenTest

It would be nice if ZenTest were registered as a development dependency. ZenTest 4.9.0 can only be installed under the latest rubygems version. See seattlerb/zentest#38.

That means in order to use rubyinline on a production server, you have to push that server to the latest rubygems. This is a pretty onerous requirement for a testing dependency.

Adding Module.options causes incompatibilities

(crossposted from http://rubyforge.org/tracker/index.php?func=detail&aid=28657&group_id=440&atid=1774, I hope that's not a problem?)

RubyInline defines 'attr_reader :options' on the core Module object. This causes Sass to break (see below if you want
to know the details*)

Would it be possible to not patch core classes in this way? Or if that's absolutely necessary, at least rename it to, say, :rubyinline_options.

* it has a Sass::Plugin module which uses method_missing to forward methods to a compiler object. One of those methods was 'options', but once RubyInline is required, Sass::Plugin.options just returns nil)

Conflict with Celluloid?

After a recent update to a Rails app I'm working on, I found that I cannot load ZenTest and Celluloid together. Still tracking this down more specifically, but here's my initial backtrace:

vendor/bundle/ruby/2.0.0/gems/celluloid-0.15.2/lib/celluloid/actor.rb:55:in `name': not in actor scope (Celluloid::NotActorError)
    from vendor/bundle/ruby/2.0.0/gems/ZenTest-4.9.5/lib/ZenTest.rb:13:in `block in <top (required)>'
    from vendor/bundle/ruby/2.0.0/gems/ZenTest-4.9.5/lib/ZenTest.rb:12:in `each_object'
    from vendor/bundle/ruby/2.0.0/gems/ZenTest-4.9.5/lib/ZenTest.rb:12:in `<top (required)>'
    from /Library/Ruby/Gems/2.0.0/gems/bundler-1.3.5/lib/bundler/runtime.rb:72:in `require'
    from /Library/Ruby/Gems/2.0.0/gems/bundler-1.3.5/lib/bundler/runtime.rb:72:in `block (2 levels) in require'
    from /Library/Ruby/Gems/2.0.0/gems/bundler-1.3.5/lib/bundler/runtime.rb:70:in `each'
    from /Library/Ruby/Gems/2.0.0/gems/bundler-1.3.5/lib/bundler/runtime.rb:70:in `block in require'
    from /Library/Ruby/Gems/2.0.0/gems/bundler-1.3.5/lib/bundler/runtime.rb:59:in `each'
    from /Library/Ruby/Gems/2.0.0/gems/bundler-1.3.5/lib/bundler/runtime.rb:59:in `require'
    from /Library/Ruby/Gems/2.0.0/gems/bundler-1.3.5/lib/bundler.rb:132:in `require'
    from config/application.rb:7:in `<top (required)>'
    from config/environment.rb:2:in `require'
    from config/environment.rb:2:in `<top (required)>'
    from config.ru:3:in `require'
    from config.ru:3:in `block in <main>'
    from vendor/bundle/ruby/2.0.0/gems/rack-1.4.5/lib/rack/builder.rb:51:in `instance_eval'
    from vendor/bundle/ruby/2.0.0/gems/rack-1.4.5/lib/rack/builder.rb:51:in `initialize'
    from config.ru:1:in `new'
    from config.ru:1:in `<main>'

Rails page with rubyinline code fails on second load.

I have an inline C method that's called from a rails page. When I load the page the first time after starting the rails server, it works fine. If I reload the page in the browser, I then get :

LoadError (require on C:/Users/abc def/.ruby_inline/ruby-1.8/Inline__cb89593d1f9fe3ecdb2178215eee80ae.so failed):

The files mentioned does exist. Any ideas ? Is ti due to the space in the windows user name in the path ?

Feature request: pretty print of C code

I think it is pretty nice to let the inline code be indented according to Ruby - when in Ruby:

  inline do |builder|
    builder.prefix %{
      #define MATCH(A,B) ((equal[A] & equal[B]) != 0)
    }
  end

The resulting C code will have a lot of extra white space - that does not affect the code, but properly indented code is nicer when debugging. I am pretty sure there is way to auto-correct the indentation in the C code.

release the latest version of rubyinline

Since RubyInline doesn't support Bundler's :git feature (doesn't store the gemspec in repo), it would be nice to release the latest version of the library to rubygems.

Confusion over name of ".so" file

Hi folks,

Note: I mistakenly filed this at Rubyforge. This new item is per Ryan's instructions.
Note2: Issue #27: "RubyInstaller compatibility" apparently describes the same problem. I'm not qualified to supply the fix, so I haven't included any of the details asked for in that issue.
Now, on with the show:

I'm attempting to use RubyInLine under windows 7 (64 bit). (Other info below.)

My problem occurs trying to run the example script:

ruby example.rb

I get the following:

ruby example.rb
C:/Ruby187/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in gem_original_require': no such file to load -- c:\Users\bwilfley/.ruby_inline/ruby-1.8/Inline_MyTest_957b1a49e8ad50000ecc5982fd89874a.so (LoadError) from C:/Ruby187/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:inrequire'
from C:/Ruby187/lib/ruby/gems/1.8/gems/RubyInline-3.11.3/lib/inline.rb:519:in load' from C:/Ruby187/lib/ruby/gems/1.8/gems/RubyInline-3.11.3/lib/inline.rb:844:ininline'
from example.rb:18

I look in my ~/.ruby_inline\ruby-1.8 directory and I have:
a.exe
Inline_MyTest_957b1a49e8ad50000ecc5982fd89874a.c

Evidently, the .c file is being generated and then compiled. But the file created by the compilation is a.out, not: Inline_MyTest_957b1a49e8ad50000ecc5982fd89874a.so

Any thoughts??

Thanks for your help,

Brian

My configuration is as follows:
Running Ruby 1.8.7 from the Windows one-click installer:
ruby 1.8.7 (2012-10-12 patchlevel 371) [i386-mingw32]

I'm using the "DevKit" from the folks who make the installer. This gives me gcc under the mingw32 environment. Before running these tests I set the DevKit environment with:

devkitvars.bat

Here is the gem environment
RubyGems Environment:

  • RUBYGEMS VERSION: 1.8.24
  • RUBY VERSION: 1.8.7 (2012-10-12 patchlevel 371) [i386-mingw32]
  • INSTALLATION DIRECTORY: C:/Ruby187/lib/ruby/gems/1.8
  • RUBY EXECUTABLE: C:/Ruby187/bin/ruby.exe
  • EXECUTABLE DIRECTORY: C:/Ruby187/bin
  • RUBYGEMS PLATFORMS:
    • ruby
    • x86-mingw32
  • GEM PATHS:
    • C:/Ruby187/lib/ruby/gems/1.8
    • c:/Users/bwilfley/.gem/ruby/1.8
  • GEM CONFIGURATION:
    • :update_sources => true
    • :verbose => true
    • :benchmark => false
    • :backtrace => false
    • :bulk_threshold => 1000
  • REMOTE SOURCES:

zentest dependency means this gem can't be used on heroku

I was trying to use https://github.com/kiyoka/fuzzy-string-match which depends on rubyinline on a project and when i deployed to heroku i found out that i couldn't because zentest requires a more modern versions of rake than heroku supports. This isn't really a bug since i don't see heroku deployment a major interest of a gem like this, but I thought I would put this on your radar since you have at least one project downstream that does.

add_compile_flags not working for '-lsqlite3'

I am trying to add compiler flags. '-w' is working but '-lsqlite3' is not.
I tried printing builder.flags and it shows both '-w' and '-lsqlite3'.
Note: -lsqlite is working fine when I am using it with gcc only.

zentest dependency

Please correct me if I'm wrong, but wouldn't it be possible to remove the dependency on ZenTest, since that isn't necessary to run RubyInline? If possible it would be great if the dependency could be axed.

RubyInstaller compatibility

Besides requiring devkit i had to change at line 583 in inline.rb this "("-L#{RbConfig::CONFIG['libdir']}" if sane)" to that ("-L#{RbConfig::CONFIG['libdir']}"). It kept naming the output file in "...ruby_inline\ruby-1.9.1" "a.exe" (standard output if no output destination is provided) until I did so. Therefore the .so RubyInline looked for wasn't found. I don't know if this is a general solution or if it just works for me. But perhaps someone can look into this. And that devkit should be requiered in combination with RubyInstaller should perhaps also be mentioned somewhere in a faq just for ease.

Gcc / windows error.

I get the following error when I try to run a test program on windows :

c:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/gems/RubyInline-3.11.0/lib/inline.rb:590:in ``': No such file or directory - gcc -shared -s -Wl,--enable-auto-image-base,--enable-auto-import,--export-all -g -O2 -DFD_SETSIZE=256 -I c:/RailsInstaller/Ruby1.8.7/lib/ruby/1.8/i386-mingw32 -I c:/RailsInstaller/Ruby1.8.7/include -Lc:/RailsInstaller/Ruby1.8.7/lib -o "C:\Users\zzz/.ruby_inline/ruby-1.8/Inline__cb89593d1f9fe3ecdb2178215eee80ae.so" "C:/Users/zzz/.ruby_inline/ruby-1.8/Inline__cb89593d1f9fe3ecdb2178215eee80ae.c" -Wl,--enable-auto-import -Lc:/RailsInstaller/Ruby1.8.7/lib -lmsvcrt-ruby18 (Errno::ENOENT)
from c:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/gems/RubyInline-3.11.0/lib/inline.rb:590:inbuild' from c:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/gems/RubyInline-3.11.0/lib/inline.rb:826:in inline'
from E:/SR/documents/eclipse/checkup/ruby_trial_code/cinline.rb:13

I've got gcc installed, and the "gcc ..." line above will run with no errors on the command line.

Any ideas ?

Just a quick question about using C libraries with rubyinline

I was thinking of trying my hand at building a voxel engine using ruby. I want to build one because I've never done any 3D application building and voxels sound interesting to me.
I want to do it in ruby because well, I like ruby and I understand it.
Thing is ruby is kinda slow so obviously I'd do well to program bits of it in C, so I want to use rubyinline for it.
My question is just, can I use c libraries (like graphic libraries for rendering) within any C inline code, if so how?

My second question is can we access ruby methods from within the C inline code? again, if so how?

I'm mostly just looking for directions to resources that could answer those questions and any others that might spring up.

Make the generated c/so name suffix a bit longer

So far RubyInline uses 4 hex-digits of the hash of the concatenated names of generated routines as a suffix of the c/so file name. I guess this works in 99% of cases, but I have quite uncommon project, which generates the RubyInline code on-the-fly. The problem is that when running tests I have hundreds of RubyInline generated files (one of the routine names if random, to "ensure" that the names of c/so files are different for classes with the same regular routines) and usually I get name collisions, due to the fact that the c/so namespace is too narrow. I guess extending the file name suffix from 4 to 8 hex-digits would solve the issue in 99,99% of cases.
The project is Rod (Ruby Object Database) https://github.com/apohllo/rod

Colission with inline gem

There is a gem named inline, which also defines inline.rb -> its not possile to have both installed.
Rename to e.g. ruby_inline.rb

Pass N Arrays in rubyinline as a parameter

Hello, I dont know how to pass some parameters in rubyinline. I got the code below

inline do |builder|
builder.c_raw '
static VALUE teste(int argc, VALUE argv, VALUE self) {
int w1, w2, w3, w4, w5, w6, cont = 0;
long i, len;
VALUE arr = RARRAY_PTR(self); / vetor */
len = RARRAY_LEN(self); /
Tamanho do vetor */

and the call method:

numbers = [1,2,4,3,6,7,8,9,14,17,21,35]

p numbers.teste

teste is the c method that we need to pass some parameters! I really have no idea what I am missing!

could you help me?

thanks

Pass type def in inline c

I've tried to use any builder arguments but I didn't find any argument that works with my typedef. It defines a symbol for true and false in c. it looks like more readable.

typedef int bool;

define TRUE 1

define FALSE 0

do you know if it is possible?

"missing compatible arch" on Apple Silicon

Running rake test on an M1 mac with system ruby reports 6 tests failure, all with the same cause:

TestModule#test_argument_check_more:
LoadError: dlopen([...]/.ruby_inline/ruby-2.6.0/Inline_Foo__Bar_[...].bundle, 0x0009): missing compatible arch in [...]/test_inline.49549/.ruby_inline/ruby-2.6.0/Inline_Foo__Bar_[...].bundle - [...]/test_inline.49549/.ruby_inline/ruby-2.6.0/Inline_Foo__Bar_[...].bundle

I'm extremely new to ruby, but from my understanding the problem is that RbConfig::CONFIG['DLDFLAGS'] contains -arch arm64e, which is an architecture that cannot be used by non-system applications/services at the moment (see here).

Adding -arch arm64 to the cmd inside build fixes the tests. Being a ruby newb, I'm not sure what is the correct way to detect if running on M1. Something like if /arm64/ =~ `arch` should work, but I'm not sure what are the best practices.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.