convinius 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +83 -0
- data/convinius.gemspec +10 -0
- data/lib/convinius.rb +1 -0
- data/lib/convinius/asm.rb +38 -0
- data/lib/convinius/generator.rb +12 -0
- data/lib/convinius/to_class.rb +20 -0
- data/spec/asm_spec.rb +32 -0
- data/spec/generator_spec.rb +17 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/to_class_spec.rb +48 -0
- metadata +77 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.rvmrc
|
data/README.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
Convinius
|
2
|
+
=========
|
3
|
+
|
4
|
+
Convenience library for Rubinius-only projects.
|
5
|
+
Use `require 'convinius'` to get all features.
|
6
|
+
|
7
|
+
Installation:
|
8
|
+
|
9
|
+
gem install convinius
|
10
|
+
|
11
|
+
Running tests:
|
12
|
+
|
13
|
+
gem install rspec
|
14
|
+
rspec spec
|
15
|
+
|
16
|
+
Subclassing from arbitrary Objects
|
17
|
+
----------------------------------
|
18
|
+
in: `convinius/to_class`
|
19
|
+
|
20
|
+
If you subclass from an object, first call `to_class` on that object and
|
21
|
+
subclass the result instead:
|
22
|
+
|
23
|
+
RandomClass = Object.new
|
24
|
+
|
25
|
+
def RandomClass.to_class
|
26
|
+
[Hash, Object, Set].at rand(3)
|
27
|
+
end
|
28
|
+
|
29
|
+
class Foo < RandomClass
|
30
|
+
puts superclass
|
31
|
+
end
|
32
|
+
|
33
|
+
A more realistic example:
|
34
|
+
|
35
|
+
module Awesome
|
36
|
+
def self.to_class
|
37
|
+
Class.new { include Awesome }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Foo < Awesome
|
42
|
+
end
|
43
|
+
|
44
|
+
class Bar < Something
|
45
|
+
include Awesome
|
46
|
+
end
|
47
|
+
|
48
|
+
Convenience for Rubinius::Generator
|
49
|
+
-----------------------------------
|
50
|
+
in: `convinius/generator`
|
51
|
+
|
52
|
+
Method for generating tuples (like `make_array`):
|
53
|
+
|
54
|
+
class MyNode < Rubinius::AST::Node
|
55
|
+
def bytecode(g)
|
56
|
+
(1..5).each { |i| g.push i }
|
57
|
+
g.make_tuple 5
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
Byte Code Generator DSL
|
62
|
+
-----------------------
|
63
|
+
in: `convinius/asm`
|
64
|
+
|
65
|
+
Example:
|
66
|
+
|
67
|
+
include Convinius::ASM
|
68
|
+
|
69
|
+
compiled = asm do
|
70
|
+
push 1
|
71
|
+
push 2
|
72
|
+
send :+, 1
|
73
|
+
end
|
74
|
+
|
75
|
+
p compiled.call
|
76
|
+
|
77
|
+
If block takes an argument, it won't use `instance_eval`:
|
78
|
+
|
79
|
+
Convinius::ASM.new do |g|
|
80
|
+
g.push 1
|
81
|
+
g.push 2
|
82
|
+
g.send :+, 1
|
83
|
+
end
|
data/convinius.gemspec
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'convinius'
|
3
|
+
s.version = '0.1.0'
|
4
|
+
s.date = '2011-01-26'
|
5
|
+
s.description = 'Convenience library for Rubinius-only projects.'
|
6
|
+
s.summary = s.description
|
7
|
+
s.authors = ['Konstantin Haase']
|
8
|
+
s.email = 'k.haase@finn.de'
|
9
|
+
s.files = `git ls-files`.split("\n")
|
10
|
+
end
|
data/lib/convinius.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'convinius/to_class'
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Convinius
|
2
|
+
module ASM
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def asm(file = "(asm)", line = 1, method = :call, &block)
|
6
|
+
g = Rubinius::Generator.new
|
7
|
+
g.name = method.to_sym
|
8
|
+
g.file = file.to_sym
|
9
|
+
g.set_line line
|
10
|
+
|
11
|
+
g.required_args = 0
|
12
|
+
g.total_args = 0
|
13
|
+
g.splat_index = nil
|
14
|
+
|
15
|
+
g.local_count = 0
|
16
|
+
g.local_names = []
|
17
|
+
|
18
|
+
block.arity > 0 ? yield(g) : g.instance_eval(&block)
|
19
|
+
|
20
|
+
g.ret
|
21
|
+
g.close
|
22
|
+
|
23
|
+
g.encode
|
24
|
+
cm = g.package Rubinius::CompiledMethod
|
25
|
+
puts cm.decode if $DEBUG
|
26
|
+
|
27
|
+
code = Object.new
|
28
|
+
ss = Rubinius::StaticScope.new Object
|
29
|
+
Rubinius.attach_method g.name, cm, ss, code
|
30
|
+
|
31
|
+
code
|
32
|
+
end
|
33
|
+
|
34
|
+
class << self
|
35
|
+
alias new asm
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Convinius
|
2
|
+
module ToClass
|
3
|
+
module ClassMethods
|
4
|
+
extend_object Class
|
5
|
+
|
6
|
+
def new(sclass = Object, *args)
|
7
|
+
sclass = sclass.to_class if sclass.respond_to? :to_class
|
8
|
+
super(sclass, *args)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module InstanceMethods
|
13
|
+
append_features Class
|
14
|
+
|
15
|
+
def to_class
|
16
|
+
self
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/asm_spec.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'convinius/asm'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Convinius::ASM do
|
5
|
+
context 'asm with instance_eval' do
|
6
|
+
include Convinius::ASM
|
7
|
+
|
8
|
+
subject do
|
9
|
+
asm do
|
10
|
+
push 1
|
11
|
+
push 2
|
12
|
+
send :+, 1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it { should respond_to(:call) }
|
17
|
+
it { should evaluate_to(3) }
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'new without instance_eval' do
|
21
|
+
subject do
|
22
|
+
Convinius::ASM.new do |g|
|
23
|
+
g.push 1
|
24
|
+
g.push 2
|
25
|
+
g.send :+, 1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it { should respond_to(:call) }
|
30
|
+
it { should evaluate_to(3) }
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'convinius/asm'
|
2
|
+
require 'convinius/generator'
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Convinius::Generator do
|
6
|
+
context 'make_tuple' do
|
7
|
+
subject do
|
8
|
+
Convinius::ASM.new do
|
9
|
+
push 1
|
10
|
+
push 2
|
11
|
+
make_tuple 2
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it { should evaluate_to(Rubinius::Tuple[1, 2]) }
|
16
|
+
end
|
17
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'convinius/to_class'
|
2
|
+
|
3
|
+
describe Convinius::ToClass do
|
4
|
+
subject do
|
5
|
+
class_loop = Object.new
|
6
|
+
|
7
|
+
class << class_loop
|
8
|
+
attr_accessor :pos
|
9
|
+
attr_accessor :list
|
10
|
+
|
11
|
+
def to_class
|
12
|
+
sclass = list.at(pos % list.size)
|
13
|
+
self.pos += 1
|
14
|
+
sclass
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class_loop
|
19
|
+
end
|
20
|
+
|
21
|
+
before do
|
22
|
+
subject.pos = 0
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should not break normal subclassing' do
|
26
|
+
class Foo; end
|
27
|
+
class Bar < Foo; end
|
28
|
+
Foo.superclass.should == Object
|
29
|
+
Bar.superclass.should == Foo
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should allow custom subclassing logic' do
|
33
|
+
subject.list = [Object, Array, Hash]
|
34
|
+
Class.new(subject).superclass == Object
|
35
|
+
Class.new(subject).superclass == Array
|
36
|
+
Class.new(subject).superclass == Hash
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should work with subclassing syntax' do
|
40
|
+
subject.list = [Object, Array, Hash]
|
41
|
+
class FromObject < subject; end
|
42
|
+
class FromArray < subject; end
|
43
|
+
class FromHash < subject; end
|
44
|
+
FromObject.superclass.should == Object
|
45
|
+
FromArray.superclass.should == Array
|
46
|
+
FromHash.superclass.should == Hash
|
47
|
+
end
|
48
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: convinius
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Konstantin Haase
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-01-26 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: Convenience library for Rubinius-only projects.
|
23
|
+
email: k.haase@finn.de
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- .gitignore
|
32
|
+
- README.md
|
33
|
+
- convinius.gemspec
|
34
|
+
- lib/convinius.rb
|
35
|
+
- lib/convinius/asm.rb
|
36
|
+
- lib/convinius/generator.rb
|
37
|
+
- lib/convinius/to_class.rb
|
38
|
+
- spec/asm_spec.rb
|
39
|
+
- spec/generator_spec.rb
|
40
|
+
- spec/spec_helper.rb
|
41
|
+
- spec/to_class_spec.rb
|
42
|
+
has_rdoc: true
|
43
|
+
homepage:
|
44
|
+
licenses: []
|
45
|
+
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
hash: 3
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 1.3.7
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: Convenience library for Rubinius-only projects.
|
76
|
+
test_files: []
|
77
|
+
|