├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── bin └── rake ├── ext └── melt │ ├── MeltService.java │ ├── extconf.rb │ ├── melt.c │ └── melt.h ├── lib └── melt.rb ├── melt.gemspec └── test ├── minitest_helper.rb └── test_melt.rb /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | *.bundle 11 | *.so 12 | *.jar 13 | *.o 14 | *.a 15 | mkmf.log 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | script: bin/rake ci:test 3 | rvm: 4 | - 2.2.3 5 | - jruby-9.0.3.0 6 | - jruby-19mode 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.3 (2015-03-02) 2 | 3 | * fixed compilation by @tom-lord 4 | 5 | # 0.2 (2015-02-23) 6 | 7 | * initial JRuby support 8 | 9 | # 0.1 (2015-02-22) 10 | 11 | * initial Ruby 2.2 support 12 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in melt.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Josef Šimánek 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Melt [![Build Status](https://travis-ci.org/zizkovrb/melt.svg?branch=master)](https://travis-ci.org/zizkovrb/melt) 2 | 3 | [There is no way to unfreeze a frozen object.](http://ruby-doc.org/core-2.2.0/Object.html#method-i-freeze) Really? Have you ever heard about icebergs or icicles? What about melting? 4 | 5 | ![no way to unfreeze?](http://media.giphy.com/media/Et9WoN2Aejm3C/giphy.gif) 6 | 7 | ## Compatibility 8 | 9 | Works with CRuby and JRuby. 10 | 11 | ## Installation 12 | 13 | Add this line to your application's Gemfile: 14 | 15 | ```ruby 16 | gem 'melt' 17 | ``` 18 | 19 | And then execute: 20 | 21 | $ bundle 22 | 23 | Or install it yourself as: 24 | 25 | $ gem install melt 26 | 27 | ## Usage 28 | 29 | ```ruby 30 | require 'melt' 31 | 32 | icicle = "----->" 33 | 34 | # winter 35 | icicle.freeze 36 | icicle.frozen? #=> true 37 | 38 | # spring 39 | icicle.melt 40 | icicle.frozen? #=> false 41 | ``` 42 | 43 | ## Contributing 44 | 45 | 1. Fork it ( https://github.com/zizkovrb/melt/fork ) 46 | 2. Create your feature branch (`git checkout -b my-new-feature`) 47 | 3. Commit your changes (`git commit -am 'Add some feature'`) 48 | 4. Push to the branch (`git push origin my-new-feature`) 49 | 5. Create a new Pull Request 50 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require "rake/testtask" 3 | 4 | Rake::TestTask.new(:test) do |t| 5 | t.libs << "test" 6 | end 7 | 8 | if RUBY_PLATFORM =~ /java/ 9 | require 'rake/javaextensiontask' 10 | Rake::JavaExtensionTask.new('melt') do |ext| 11 | ext.lib_dir = "lib/melt" 12 | end 13 | else 14 | require "rake/extensiontask" 15 | Rake::ExtensionTask.new("melt") do |ext| 16 | ext.lib_dir = "lib/melt" 17 | end 18 | end 19 | 20 | task :default => [:clean, :build, :test] 21 | task :build => :compile 22 | 23 | namespace :ci do 24 | task :test => [:default, :install] 25 | end 26 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'rake' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('rake', 'rake') 17 | -------------------------------------------------------------------------------- /ext/melt/MeltService.java: -------------------------------------------------------------------------------- 1 | package org.zizkovrb.melt; 2 | 3 | import java.io.IOException; 4 | 5 | import org.jruby.Ruby; 6 | import org.jruby.RubyClass; 7 | import org.jruby.RubyModule; 8 | import org.jruby.RubyObject; 9 | import org.jruby.anno.JRubyMethod; 10 | import org.jruby.runtime.ObjectAllocator; 11 | import org.jruby.runtime.ThreadContext; 12 | import org.jruby.runtime.builtin.IRubyObject; 13 | import org.jruby.runtime.load.BasicLibraryService; 14 | 15 | public class MeltService implements BasicLibraryService { 16 | private Ruby runtime; 17 | 18 | public boolean basicLoad(Ruby runtime) throws IOException { 19 | this.runtime = runtime; 20 | RubyModule melt = runtime.defineModule("Melt"); 21 | 22 | RubyClass down = melt.defineClassUnder("Down", runtime.getObject(), new ObjectAllocator() { 23 | public IRubyObject allocate(Ruby runtime, RubyClass rubyClass) { 24 | return new MeltDown(runtime, rubyClass); 25 | } 26 | 27 | }); 28 | 29 | down.defineAnnotatedMethods(MeltDown.class); 30 | return true; 31 | } 32 | 33 | public class MeltDown extends RubyObject { 34 | public MeltDown(final Ruby runtime, RubyClass rubyClass) { 35 | super(runtime, rubyClass); 36 | } 37 | 38 | @JRubyMethod 39 | public IRubyObject execute(ThreadContext context, IRubyObject target) { 40 | if(target.isFrozen()) { 41 | target.setFrozen(false); 42 | } 43 | return target; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ext/melt/extconf.rb: -------------------------------------------------------------------------------- 1 | require "mkmf" 2 | 3 | create_makefile("melt/melt") 4 | -------------------------------------------------------------------------------- /ext/melt/melt.c: -------------------------------------------------------------------------------- 1 | #include "melt.h" 2 | 3 | VALUE melt(VALUE self) { 4 | RBASIC(self)->flags ^= FL_FREEZE; 5 | return self; 6 | } 7 | 8 | void Init_melt(void) { 9 | rb_define_method(rb_cObject, "melt", melt, 0); 10 | } 11 | -------------------------------------------------------------------------------- /ext/melt/melt.h: -------------------------------------------------------------------------------- 1 | #ifndef MELT_H 2 | #define MELT_H 1 3 | 4 | #include "ruby.h" 5 | 6 | VALUE melt(VALUE self); 7 | 8 | #endif /* MELT_H */ 9 | -------------------------------------------------------------------------------- /lib/melt.rb: -------------------------------------------------------------------------------- 1 | require "melt/melt" 2 | 3 | if RUBY_PLATFORM =~ /java/ 4 | class Object 5 | def melt 6 | require 'jruby' 7 | org.zizkovrb.melt.MeltService.new.basicLoad(JRuby.runtime) 8 | Melt::Down.new.execute(self) 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /melt.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "melt" 7 | spec.version = "0.3" 8 | spec.authors = ["Josef Šimánek"] 9 | spec.email = ["josef.simanek@gmail.com"] 10 | 11 | if spec.respond_to?(:metadata) 12 | spec.metadata['allowed_push_host'] = "https://rubygems.org" 13 | end 14 | 15 | spec.summary = %q{There is no way to unfreeze a frozen object. Really?} 16 | spec.description = %q{Have you ever heard about icebergs or icicles? What about melting?} 17 | spec.homepage = "https://github.com/zizkovrb/melt" 18 | spec.license = "MIT" 19 | 20 | spec.files = Dir.glob("ext/**/*.{c,h,java,rb}") + Dir.glob("lib/**/*.rb") 21 | spec.require_paths = ["lib"] 22 | 23 | if RUBY_PLATFORM =~ /java/ 24 | spec.platform = "java" 25 | spec.files << "lib/melt/melt.jar" 26 | else 27 | spec.extensions = ["ext/melt/extconf.rb"] 28 | end 29 | 30 | spec.add_development_dependency "bundler", "~> 1.7" 31 | spec.add_development_dependency "rake", "~> 10.0" 32 | spec.add_development_dependency "rake-compiler" 33 | spec.add_development_dependency "minitest" 34 | end 35 | -------------------------------------------------------------------------------- /test/minitest_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) 2 | require 'melt' 3 | 4 | require 'minitest/autorun' 5 | -------------------------------------------------------------------------------- /test/test_melt.rb: -------------------------------------------------------------------------------- 1 | require 'minitest_helper' 2 | require 'melt' 3 | 4 | class TestMelt < Minitest::Test 5 | def test_it_melt 6 | # winter 7 | icicle.freeze 8 | assert icicle.frozen?, 'Icicle is not frozen!' 9 | 10 | # spring 11 | icicle.melt 12 | refute icicle.frozen?, 'Icile is not melted!' 13 | end 14 | 15 | def test_melted_is_same_object 16 | oid = icicle.object_id 17 | 18 | # winter 19 | icicle.freeze 20 | assert_equal oid, icicle.object_id 21 | 22 | # spring 23 | icicle.melt 24 | assert_equal oid, icicle.object_id 25 | end 26 | 27 | def icicle 28 | @icicle ||= "----->" 29 | end 30 | end 31 | --------------------------------------------------------------------------------