hubris 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. data/.gitignore +31 -0
  2. data/.rvmrc +2 -0
  3. data/Gemfile +11 -0
  4. data/Haskell/Hubrify.hs +69 -0
  5. data/Haskell/LICENSE +22 -0
  6. data/Haskell/Language/Ruby/Foo.hs +20 -0
  7. data/Haskell/Language/Ruby/Hubris/Binding.hsc +214 -0
  8. data/Haskell/Language/Ruby/Hubris/GHCBuild.hs +46 -0
  9. data/Haskell/Language/Ruby/Hubris/Hash.hs +27 -0
  10. data/Haskell/Language/Ruby/Hubris/Interpolator.hs +22 -0
  11. data/Haskell/Language/Ruby/Hubris/LibraryBuilder.hs +181 -0
  12. data/Haskell/Language/Ruby/Hubris/ZCode.hs +68 -0
  13. data/Haskell/Language/Ruby/Hubris.hs +254 -0
  14. data/Haskell/Language/Ruby/Wrappers.hs +32 -0
  15. data/Haskell/Language/Ruby/testLib.hs +9 -0
  16. data/Haskell/Setup.hs +31 -0
  17. data/Haskell/cbits/rshim.c +46 -0
  18. data/Haskell/cbits/rshim.h +50 -0
  19. data/Haskell/hubris.cabal +53 -0
  20. data/INSTALL +21 -0
  21. data/Manifest.txt +22 -0
  22. data/PostInstall.txt +1 -0
  23. data/README.markdown +107 -0
  24. data/Rakefile +46 -43
  25. data/VERSION +1 -0
  26. data/doc/CommonErrors.txt +18 -0
  27. data/doc/CommonErrors.txt~HEAD +18 -0
  28. data/doc/don_feedback.txt +25 -0
  29. data/doc/haskell-hubris.tex +242 -0
  30. data/doc/new_interface.rb +74 -0
  31. data/doc/ruby-hubris.tex +176 -0
  32. data/doc/wisdom_of_ancients.txt +55 -0
  33. data/ext/hubris.rb +4 -0
  34. data/ext/stub/extconf.rb +5 -0
  35. data/ext/{HubrisStubLoader.c → stub/stub.c} +1 -1
  36. data/hubris.gemspec +31 -0
  37. data/lib/Makefile +181 -0
  38. data/lib/hubris/version.rb +3 -0
  39. data/lib/hubris.rb +16 -13
  40. data/rspec.rake +21 -0
  41. data/sample/Fibonacci.hs +2 -2
  42. data/sample/config.ru +3 -1
  43. data/script/ci.sh +25 -0
  44. data/script/console +10 -0
  45. data/spec/hubris_spec.rb +173 -47
  46. data/tasks/extconf/stub.rake +43 -0
  47. data/tasks/extconf.rake +13 -0
  48. metadata +118 -27
  49. data/ext/extconf.rb +0 -5
data/README.markdown ADDED
@@ -0,0 +1,107 @@
1
+ # Hubris
2
+
3
+ ## Description
4
+
5
+ Hubris is a bridge between Ruby and Haskell, between love and bondage,
6
+ between slothful indolence and raw, blazing speed. Hubris will wash
7
+ your car, lie to your boss, and salvage your love life. If you are
8
+ very, very lucky, it might also let you get some functional goodness
9
+ into your ruby programs through the back door.
10
+
11
+ I probably don't have to say this, but patches are very much
12
+ welcome. If you have trouble installing it, tell me, and help me
13
+ improve the docs.
14
+
15
+ ## Synopsis
16
+
17
+ The best docs, as ever, are in the tests, but as a quick precis, you
18
+ can use it a little like this:
19
+
20
+ require 'hubris' # best line ever
21
+
22
+ class Target
23
+ hubris :inline =>"triple::Int->Int; triple n = 3*n"
24
+ end
25
+
26
+ t = Target.new
27
+ puts t.triple(10)
28
+ => 30
29
+
30
+ There are a few restrictions. All functions take one argument and
31
+ return one value: this shouldn't be a major problem because you can
32
+ pass arrays of arguments in if you need more. Hubris can currently
33
+ handle numbers, strings, basic types (like nil, true and false),
34
+ arrays and hashes. There will probably be some Ruby structures
35
+ (modules, regular expressions, etc) that won't ever be handled
36
+ natively unless someone can convince me it's a sensible thing to do.
37
+
38
+ Hubris will refuse to compile Haskell code that produces any
39
+ warnings. You can suppress this admittedly fairly strict behaviour by
40
+ passing the ":no_strict => true" flag, but in your heart of hearts
41
+ you'll know you've done the wrong thing.
42
+
43
+ There are also two other modes:
44
+
45
+ hubris :source => "MyCoolModule.hs"
46
+
47
+ which loads a source file on disk (in the same directory as your ruby),
48
+ and
49
+
50
+ hubris :module => "Data.ByteString", :packages => ["bytestring"]
51
+
52
+ which will load the Data.ByteString module which is installed on the
53
+ system. In this case, we also need to let the Haskell side know that
54
+ we'll be using the "bytestring" package, so we pass that too: You may
55
+ need to load extra packages with :inline and :source as well, and
56
+ that's supported.
57
+
58
+
59
+ ## Requirements
60
+
61
+ * ghc 6.10 (to bootstrap 6.12) and cabal-install. This comes with the
62
+ Haskell Platform
63
+ * ruby 1.8.6 or higher (most heavily tested on 1.9.1)
64
+ * Linux or Mac. See
65
+ <http://www.shimweasel.com/2009/09/14/unprincipled-skulduggery-with-ghc-6-12-dylibs-on-mac-os-x>
66
+ and the following entry for more info on the Mac build.
67
+ * zsh or bash
68
+ * git
69
+
70
+ ## Install
71
+
72
+ Better instructions for [Linux](http://wiki.github.com/mwotton/Hubris/installation-of-ghc-6121-on-ubuntu-910) and [Mac](http://wiki.github.com/mwotton/Hubris/installation-of-ghc-6121-on-mac-os-x)
73
+
74
+ ## Contributors
75
+
76
+ * Mark Wotton
77
+ * James Britt
78
+ * Josh Price
79
+ * Tatsuhiro Ujihisa
80
+
81
+ ## License
82
+
83
+ (The MIT License)
84
+
85
+ Copyright (c) 2009 Mark Wotton
86
+
87
+ Permission is hereby granted, free of charge, to any person obtaining
88
+ a copy of this software and associated documentation files (the
89
+ 'Software'), to deal in the Software without restriction, including
90
+ without limitation the rights to use, copy, modify, merge, publish,
91
+ distribute, sublicense, and/or sell copies of the Software, and to
92
+ permit persons to whom the Software is furnished to do so, subject to
93
+ the following conditions:
94
+
95
+ The above copyright notice and this permission notice shall be
96
+ included in all copies or substantial portions of the Software.
97
+
98
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
99
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
100
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
101
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
102
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
103
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
104
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
105
+
106
+
107
+ [haskell_platform]: http://hackage.haskell.org/platform/
data/Rakefile CHANGED
@@ -1,51 +1,54 @@
1
- require 'rubygems'
2
- #gem 'hoe', '>= 2.1.0'
3
- #require 'hoe'
1
+
2
+
3
+ require 'bundler'
4
+ Bundler::GemHelper.install_tasks
5
+ require 'rake'
4
6
  require 'fileutils'
5
- require './lib/hubris'
6
-
7
- # Hoe.plugin :newgem
8
- # Hoe.plugin :website
9
- # Hoe.plugin :cucumberfeatures
10
-
11
- # Generate all the Rake tasks
12
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
13
- #$hoe = Hoe.spec 'hubris' do
14
- # self.developer 'Mark Wotton', 'mwotton@gmail.com'
15
- # self.rubyforge_name = "hubris"
16
- # self.summary = 'tool to help build .so files from haskell code for use in Ruby via dl'
17
- # self.post_install_message = 'PostInstall.txt'
18
- # self.readme_file = "README.markdown"
19
- # self.history_file = "HISTORY.markdown"
20
- #end
21
-
22
- #require 'newgem/tasks'
23
- # Dir['tasks/**/*.rake'].each { |t| load t }
24
-
25
-
26
- #file "lib/RubyMap.hs" => ["lib/RubyMap.chs"] do
27
- # str = "c2hs -v --cppopts='-I" + Hubris::RubyHeader + "' --cpp=gcc --cppopts=-E --cppopts=-xc lib/RubyMap.chs"
28
- # # print str
29
- # system(str)
30
- #end
31
-
32
- require 'spec'
33
- require 'spec/rake/spectask'
34
-
35
- # desc "Run the specs under spec/"
36
- # all_examples = Spec::Rake::SpecTask.new do |t|
37
- # t.spec_opts = ['--options', "spec/spec.opts"]
38
- # t.spec_files = FileList['spec/*.rb']
7
+
8
+ # require 'rake-compiler'
9
+ require 'rake/extensiontask'
10
+ # require 'rake/extensiontesttask'
11
+
12
+
13
+ # task "build:native" => [:no_extconf, :native, :build] do
14
+ # file = "pkg/stub-#{`cat VERSION`.chomp}.gem"
15
+ # mv file, "#{file.ext}-i686-linux.gem"
39
16
  # end
40
17
 
41
- # task :spec => ["lib/RubyMap.hs"]
18
+
19
+ Rake::ExtensionTask.new('stub')
20
+
21
+ # intended to be called by the gem builder
22
+ task :haskell_compile => [:compile] do
23
+ ghc_version='/usr/local/bin/ghc' # FIXME, should be able to pick
24
+ # this out from somewhere
25
+ # write the Includes file
26
+ pwd =`pwd`.strip
27
+ arch_headers = "#{RbConfig::CONFIG['rubyhdrdir']}/#{RbConfig::CONFIG['arch']}"
28
+ lib_dir = RbConfig::CONFIG['libdir']
29
+ headers = RbConfig::CONFIG['rubyhdrdir']
30
+ File.open("#{pwd}/Haskell/Language/Ruby/Hubris/Includes.hs","w") do |file|
31
+ file.write "module Language.Ruby.Hubris.Includes where
32
+ extraIncludeDirs = [\"#{headers}\", \"#{arch_headers}\"]"
33
+ end
34
+ # command="cd Haskell; cabal update; cabal install
35
+ # --extra-include-dirs=#{RbConfig::CONFIG['rubyhdrdir']}
36
+ # --extra-include-dirs=#{RbConfig::CONFIG['rubyhdrdir']}/#{RbConfig::CONFIG['arch']} --extra-lib-dirs=#{RbConfig::CONFIG['libdir']} --user --enable-shared --with-ghc=#{ghc_version}"
37
+ command="cd Haskell; cabal install --extra-include-dirs=#{arch_headers} --extra-include-dirs=#{headers} --extra-lib-dirs=#{lib_dir} --user --enable-shared --with-ghc=#{ghc_version}"
38
+ result=%x{#{command}}
39
+ raise "ERROR: ran #{command}, got #{result}" unless $?.success?
40
+ end
41
+
42
+ task :no_extconf do
43
+ $gemspec.extensions = []
44
+ end
45
+
46
+ task :default => :haskell_compile
42
47
 
43
48
  task :clean do
44
49
  FileList[File.expand_path("~/.hubris_cache/*"),
45
- 'lib*.so', 'lib/*.o', 'libfoo_*.bundle' ].each do |f|
46
- begin
47
- File.delete(f)
48
- rescue
49
- end
50
+ 'lib*.so', 'lib/*.o' ].each do |f|
51
+ File.delete(f) rescue nil
50
52
  end
51
53
  end
54
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.3
@@ -0,0 +1,18 @@
1
+ this is a quick guide to diagnosing what could be wrong.
2
+
3
+ This:
4
+ """
5
+ /var/folders/Dz/Dz5WpFSZGUaFLA8jp8kT5E+++TM/-Tmp-/working_source.hs:7:7:
6
+ Could not find module `Foreign':
7
+ Perhaps you haven't installed the "dyn" libraries for package
8
+ `base'?
9
+ """
10
+
11
+ indicates that GHC HEAD was not installed correctly. Run something
12
+ like "find /usr/local -iname '*dyn_hi'" to check that the GHC you are
13
+ using has all its dynamic library header files installed. If it
14
+ doesn't, you probably didn't build GHC the right way: check
15
+ http://www.shimweasel.com/2009/09/16/another-awful-hack-to-ghc-6-11
16
+ and
17
+ http://www.shimweasel.com/2009/09/14/unprincipled-skulduggery-with-ghc-6-12-dylibs-on-mac-os-x
18
+ for more info.
@@ -0,0 +1,18 @@
1
+ this is a quick guide to diagnosing what could be wrong.
2
+
3
+ This:
4
+ """
5
+ /var/folders/Dz/Dz5WpFSZGUaFLA8jp8kT5E+++TM/-Tmp-/working_source.hs:7:7:
6
+ Could not find module `Foreign':
7
+ Perhaps you haven't installed the "dyn" libraries for package
8
+ `base'?
9
+ """
10
+
11
+ indicates that GHC HEAD was not installed correctly. Run something
12
+ like "find /usr/local -iname '*dyn_hi'" to check that the GHC you are
13
+ using has all its dynamic library header files installed. If it
14
+ doesn't, you probably didn't build GHC the right way: check
15
+ http://www.shimweasel.com/2009/09/16/another-awful-hack-to-ghc-6-11
16
+ and
17
+ http://www.shimweasel.com/2009/09/14/unprincipled-skulduggery-with-ghc-6-12-dylibs-on-mac-os-x
18
+ for more info.
@@ -0,0 +1,25 @@
1
+ ------------------------------------------------------------------------
2
+
3
+ Hubris
4
+ Ruby calling Haskell
5
+ - inline, dynamically compiled Haskell
6
+ - call precompiled stuff
7
+
8
+ Dream
9
+ Haskell to code would be Cabal package.
10
+ Ruby would be application.
11
+
12
+ FFI preprocessor:
13
+ Does Haskell foreign export
14
+ Generates marshalling boilerplate
15
+
16
+ Haskell code in Ruby
17
+
18
+ ------------------------------------------------------------------------
19
+
20
+ Grammar, parsing, type-driven.
21
+
22
+ Killer demo:
23
+ - Rails site,
24
+ - super clever/ fast/ multicore Haskell code
25
+
@@ -0,0 +1,242 @@
1
+ % Local Variables:
2
+ % compile-command: "/opt/local/bin/pdflatex fp-syd.tex && open fp-syd.pdf"
3
+ % End:
4
+
5
+ \documentclass{beamer}
6
+ \usepackage{listings}
7
+ \usepackage{beamerthemesplit}
8
+
9
+ \title{Hubris}
10
+ \subtitle{A Trojan Horse for Haskell}
11
+ \author{Mark Wotton \textless mwotton@shimweasel.com\textgreater}
12
+ \date{\today}
13
+
14
+ \begin{document}
15
+ \lstset{language=Haskell}
16
+ \section{Two cultures}
17
+ \frame{\titlepage}
18
+
19
+ % \subsection
20
+ \begin{frame}
21
+ \frametitle{I \ding{170} Ruby}
22
+ \begin{itemize}
23
+ \item concise and flexible
24
+ \item Big web community, many libraries
25
+ \item Fun
26
+ \end{itemize}
27
+ \end{frame}
28
+
29
+ \begin{frame}
30
+ \frametitle{I \ding{170} Haskell}
31
+ \begin{itemize}
32
+ \item<1-> Fast (optimised native code, multicore, etc)
33
+ \item<2-> Expressive - type systems don't have to suck.
34
+ \item<3-> Provably safe at compile time
35
+ \end{itemize}
36
+ \end{frame}
37
+
38
+
39
+ \begin{frame}
40
+ \frametitle{So, why do I care?}
41
+ \begin{itemize}
42
+ \item<1-> Make it easier to slap up a quick web interface to cool
43
+ haskell code.
44
+ \item<2-> Get more web-savvy devs into the Haskell community
45
+ \end{itemize}
46
+ \end{frame}
47
+
48
+ \subsection{problems with Haskell}
49
+ \begin{frame}
50
+ \frametitle{heresies}
51
+ \setlength\parskip{0.1in}
52
+
53
+ Haskell web frameworks are still niche.
54
+
55
+ It's an engineering problem, and pretty boring.
56
+
57
+ Haskell devs aren't exactly hard to find, but they don't seem to be
58
+ web guys.
59
+
60
+ \end{frame}
61
+
62
+ \subsection{problems with Ruby}
63
+ \begin{frame}
64
+ \frametitle{lies, damn lies, benchmarks}
65
+ \center{JRuby vs GHC}
66
+ \begin{tabular}{l l l l}
67
+ Program & Time &Memory & Source Size\\ \hline
68
+ reverse-complement &5 &1 &1/4\\
69
+ regex-dna &7 &3 &1/5\\
70
+ binary-trees &8 &7 &1 \\
71
+ k-nucleotide &10 &1 &1/7 \\
72
+ pidigits &18 &18 &2 \\
73
+ n-body &26 &53 &1 \\
74
+ chameneos-redux &30 &24 &1 \\
75
+ fasta &31 &142 &1 \\
76
+ fannkuch &45 &22 &1/4 \\
77
+ spectral-norm &227 &56 &1/3 \\
78
+ mandelbrot &319 &3 &1/2\\
79
+ \end{tabular}
80
+ \end{frame}
81
+
82
+
83
+
84
+ \section{Hubris}
85
+ \begin{frame}
86
+ \frametitle{Peanut butter, meet chocolate}
87
+ Ruby has a heap of web frameworks, convenience libraries, well-tested
88
+ integration with javascript + CSS.
89
+
90
+ \setlength\parskip{0.25in}
91
+
92
+ Haskell is smoking fast with rock solid type safety but a relatively tiny
93
+ community
94
+
95
+ Hubris is my bridge between the two
96
+ \end{frame}
97
+
98
+ \begin{frame}
99
+ \frametitle{Again, WHY?}
100
+ There are seventy bazillion ways of talking between languages.
101
+ \begin{itemize}
102
+ \item Web services
103
+ \item text over pipes
104
+ \item Protocol buffers, Thrift
105
+ \item COM, HOC, etc (binary interfaces)
106
+ \end{itemize}
107
+
108
+ Reasons to do it this way:
109
+ \begin{itemize}
110
+ \item it's fun (for me, anyway)
111
+ \item low fuss - no explicit mapping of function interfaces
112
+ \item easy to explore a library
113
+ \item few dependencies
114
+ \end{itemize}
115
+ \end{frame}
116
+
117
+ \lstset{language=Haskell}
118
+ \subsection{Haskell example}
119
+ \begin{frame}[fragile]
120
+ \frametitle{lazy, statically typed, and pure}
121
+ Collatz.hs
122
+ \begin{lstlisting}
123
+ module Collatz where
124
+ clMax lim = maximumBy (comparing snd) (assocs arr)
125
+ where arr = listArray (1,lim)
126
+ (0:(map depth [2..]))
127
+ step x = if even x
128
+ then div x 2
129
+ else 3 * x + 1
130
+ depth x = 1 + if n <= lim
131
+ then arr ! n
132
+ else depth n
133
+ where n = step x
134
+ \end{lstlisting}
135
+ Hubrify Collatz collatz.dylib Collatz.hs
136
+
137
+ \end{frame}
138
+
139
+ \subsection{wrap it in Ruby}
140
+ \begin{frame}[fragile]
141
+ \frametitle{actually using it}
142
+ \lstset{language=Ruby}
143
+ \begin{lstlisting}
144
+ require Hubris # my favourite line
145
+ module Collatz
146
+ hubris :module => 'collatz'
147
+ end
148
+ puts Collatz.clMax(1000000)
149
+ >> 837799
150
+ \end{lstlisting}
151
+ \end{frame}
152
+
153
+ \subsection{beneath the covers}
154
+ \begin{frame}[fragile]
155
+ \frametitle{on the Haskell side}
156
+ Hubrify loads the given source files and attempts to find the
157
+ passed-in module using the GHC API.
158
+ \lstset{language=Haskell}
159
+ \begin{lstlisting}
160
+ data RValue = T_NIL | T_FIXNUM Int | ...
161
+ type Value = CULong -- imported from Ruby
162
+ class Haskellable a where
163
+ toHaskell :: RValue -> Maybe a
164
+
165
+ class Rubyable a where
166
+ toRuby :: a -> RValue
167
+
168
+ wrap :: (Haskellable a, Rubyable b) ->
169
+ (a -> b) -> (Value -> Value)
170
+ \end{lstlisting}
171
+ \end{frame}
172
+
173
+ \begin{frame}[fragile]
174
+ \frametitle{blah}
175
+ For each top level definition f, we then typecheck.
176
+ \begin{lstlisting}
177
+ (wrap f) T_NIL == T_NIL
178
+ \end{lstlisting}
179
+ if it fits, it's exportable.
180
+
181
+ create a Haskell file exporting each valid function, add a top level
182
+ manifest, and compile into a self-contained dylib.
183
+
184
+ \end{frame}
185
+
186
+ \begin{frame}
187
+ \frametitle{On the ruby side}
188
+ No Haskell-specific information at all.
189
+
190
+ We have a manifest function we need to call to find the names of
191
+ wrapped functions. (Also gives us a convenient point to initialise
192
+ the Haskell runtime)
193
+
194
+ attach all passed functions as methods on the surrounding module
195
+
196
+ \end{frame}
197
+
198
+
199
+ % \frametitle{Predictive}
200
+ \section{Making it less sucky}
201
+ \begin{frame}
202
+ \setlength\parskip{0.1in}
203
+ \frametitle{What's been done}
204
+ caching of Haskell binaries
205
+
206
+ transparent mapping - no boilerplate
207
+
208
+ separation of concerns - no compiler on server
209
+
210
+ ported to GHC
211
+ \end{frame}
212
+
213
+ \begin{frame}
214
+ \frametitle{Still to do}
215
+ one-way bridge, no callbacks to Ruby
216
+
217
+ autoconf support to find ruby libs and includes
218
+
219
+ more serious hammering to find bugs - is it legitimate to dlopen
220
+ multiple haskell dylibs?
221
+
222
+ performance testing
223
+
224
+ \end{frame}
225
+
226
+
227
+ \begin{frame}
228
+ \frametitle{Try it out!}
229
+ install GHC 6.12 release candidate
230
+
231
+ git clone git://github.com/mwotton/HaskellHubris.git
232
+
233
+ git clone git://github.com/mwotton/Hubris.git
234
+
235
+ follow the README
236
+
237
+ tell me what's missing
238
+
239
+ patches very much welcome (thanks to Josh Price, James Britt and Tatsuhiro Ujihisa)
240
+ \end{frame}
241
+
242
+ \end{document}
@@ -0,0 +1,74 @@
1
+ # IDEAS for new interface
2
+
3
+ # option 1 (implicit method name from haskell function)
4
+ class MyClass
5
+ include Hubris
6
+ def_haskell(code)
7
+ end
8
+
9
+ # option 2 (explicit method name)
10
+ class MyClass
11
+ def_haskell(method_name,code)
12
+ end
13
+
14
+ # option 3 ()
15
+ class Module
16
+ include Hubris
17
+ end
18
+
19
+ class MyClass
20
+ inline_haskell "haskell function"
21
+ end
22
+
23
+ # option 4 (more humourous)
24
+ class Module
25
+ include Hubris
26
+ end
27
+
28
+ class MyClass
29
+ hubris "haskell function"
30
+ end
31
+
32
+ #-----------------------------------------
33
+ # include at the module or package level
34
+ #=========================================
35
+ # does importing as_class make sense? no, just include the module
36
+ # when interpreting Haskell module names replace . with ::
37
+
38
+ # importing std module as a ruby module/class
39
+ hubris :package => "containers", :module => "Data.Map", :as => "Data::Map"
40
+
41
+ # importing your own module (defaults to module)
42
+ hubris :package => "mypackage", :module => "MyModule" [, :as => "MyModule"]
43
+
44
+ # implicit package handling (haskell file in my directory)
45
+ hubris :module => "haskell/shit/MyModule"
46
+
47
+ # simpler to implement option, allows more flexibility in Ruby land
48
+ module MyRubyModule
49
+ # :packages is optional, just brings in external packages.
50
+ hubris :module => "Data.Map", :packages => ["containers","foo"]
51
+ # or
52
+ hubris :source => "MyHaskellCode.hs" # , :packages => [ ... ]
53
+ # or
54
+ hubris :inline => "foo x = x * 2"
55
+ end
56
+
57
+
58
+ # alternative
59
+
60
+ Hubris.import :package => "containers", :module => "Data.Map"
61
+
62
+ module MyRubyModule
63
+ include Hubris::Data::Map
64
+ end
65
+
66
+ # alternative2
67
+
68
+ module MyRubyModule
69
+ hubris :package => "containers", :module => "Data.Map"
70
+ end
71
+
72
+
73
+ 6:34:58 PM Josh Price: class Module; def hubris; self.class_eval { def self.h;"hubrified!";end };end;end
74
+ 6:35:10 PM Josh Price: class B;hubris;end