transfigure 1.0.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ab9e53aade4fcebb812cc2cfdbf32d32d46e743e0e8ab92dab8daf92dd3d1313
4
+ data.tar.gz: 723c3c3b50ab37ecc6da747bdade04b4369482b149e96599b1c2f3f4a2e6caf7
5
+ SHA512:
6
+ metadata.gz: 2ea20c2106c5f9808ad23979371002685fb92d001fd0abb5e880d884a54612f8b014e014c4fe774530472078b1360dac0c8c3d6c805e0253657dd280b93a9a74
7
+ data.tar.gz: 2c667b536b40c4511f9b244655249b991ec9f704518e1995ea1f94a783a5d21e2ea484333c92d18776d934208bd0fb7ae7a23ba3d3f3815a66020df63884d918
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ ## transfigure
2
+
3
+ An experimental Ruby native extension that allows changing an object's class at runtime.
4
+
5
+ ## Installation
6
+
7
+ `gem install transfigure`
8
+
9
+ ## Usage
10
+
11
+ ```ruby
12
+ require 'transfigure'
13
+ ```
14
+
15
+ The transfigure gem adds the `transfigure_into!` method onto Ruby's `Object` class. Pass it another class to switch out the object's current class to another one:
16
+
17
+ ```ruby
18
+ class Foo
19
+ end
20
+
21
+ class Bar
22
+ end
23
+
24
+ obj = Foo.new
25
+ obj.is_a?(Foo) # => true
26
+ obj.transfigure_into!(Bar)
27
+ obj.is_a?(Foo) # => false
28
+ obj.is_a?(Bar) # => true
29
+ ```
30
+
31
+ ## Requirements
32
+
33
+ The code has only been tested on MRI (cruby) 3.1 and will definitely not work on other Ruby engines like JRuby or TruffleRuby.
34
+
35
+ ## Running Tests
36
+
37
+ `bundle exec rspec`
38
+
39
+ ## Authors
40
+
41
+ * Cameron C. Dutro: http://github.com/camertron
@@ -0,0 +1,6 @@
1
+ require 'mkmf'
2
+
3
+ $CFLAGS << " -O3 "
4
+ $srcs = ["transfigure.c"]
5
+
6
+ create_makefile("transfigure/transfigure")
@@ -0,0 +1,23 @@
1
+ #include "ruby.h"
2
+
3
+ /* Copy/pasted from rbasic.h. We have to define our own copy of RBasic in order to
4
+ * remove the const annotation from the klass field, which is (rightly) marked as
5
+ * const in the original. We then force-cast the original RBasic into TFRBasic,
6
+ * which removes klass' const-ness. Now that the field is no longer const, it can
7
+ * be set easily.
8
+ *
9
+ * Forgive me father, for I have sinned.
10
+ */
11
+ struct RUBY_ALIGNAS(SIZEOF_VALUE) TFRBasic {
12
+ VALUE flags;
13
+ VALUE klass;
14
+ };
15
+
16
+ VALUE tf_transfigure_into_bang(VALUE self, VALUE target_klass) {
17
+ ((struct TFRBasic*)RBASIC(self))->klass = target_klass;
18
+ return Qnil;
19
+ }
20
+
21
+ void Init_transfigure() {
22
+ rb_define_method(rb_cObject, "transfigure_into!", RUBY_METHOD_FUNC(tf_transfigure_into_bang), 1);
23
+ }
Binary file
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Transfigure
4
+ VERSION = "1.0.0"
5
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ # load native extension
4
+ require "transfigure/transfigure"
@@ -0,0 +1,7 @@
1
+ $:.push(__dir__)
2
+
3
+ require 'rspec'
4
+ require 'transfigure'
5
+
6
+ RSpec.configure do |config|
7
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe "transfigure_into!" do
6
+ class Foo
7
+ def identify
8
+ "foo"
9
+ end
10
+ end
11
+
12
+ class Bar
13
+ def identify
14
+ "bar"
15
+ end
16
+ end
17
+
18
+ it "dynamically changes the object's class" do
19
+ obj = Foo.new
20
+ expect(obj).to be_a(Foo)
21
+
22
+ obj.transfigure_into!(Bar)
23
+ expect(obj).to be_a(Bar)
24
+ end
25
+
26
+ it "ensures the object responds to the new class's methods" do
27
+ obj = Foo.new
28
+ expect(obj.identify).to eq("foo")
29
+
30
+ obj.transfigure_into!(Bar)
31
+ expect(obj.identify).to eq("bar")
32
+ end
33
+ end
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: transfigure
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Cameron C. Dutro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-06-11 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ executables: []
16
+ extensions:
17
+ - ext/transfigure/extconf.rb
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README.md
21
+ - ext/transfigure/extconf.rb
22
+ - ext/transfigure/transfigure.c
23
+ - lib/transfigure.rb
24
+ - lib/transfigure/transfigure.bundle
25
+ - lib/transfigure/version.rb
26
+ - spec/spec_helper.rb
27
+ - spec/transfigure_spec.rb
28
+ homepage: https://github.com/camertron/transfigure
29
+ licenses:
30
+ - MIT
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 2.7.0
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubygems_version: 3.3.19
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: An experimental Ruby native extension that allows changing an object's class
51
+ at runtime.
52
+ test_files: []