[#74190] [Ruby trunk Feature#12134] Comparison between `true` and `false` — duerst@...
SXNzdWUgIzEyMTM0IGhhcyBiZWVuIHVwZGF0ZWQgYnkgTWFydGluIETDvHJzdC4KCgpUc3V5b3No
3 messages
2016/03/07
[#74269] Type systems for Ruby — Rob Blanco <ml@...>
Dear ruby-core,
5 messages
2016/03/10
[#74395] [Ruby trunk Feature#12142] Hash tables with open addressing — shyouhei@...
Issue #12142 has been updated by Shyouhei Urabe.
3 messages
2016/03/17
[ruby-core:74386] [Ruby trunk Feature#12092] Allow Object#clone to yield cloned object before freezing
From:
merch-redmine@...
Date:
2016-03-16 16:14:48 UTC
List:
ruby-core #74386
Issue #12092 has been updated by Jeremy Evans.
Nobuyoshi Nakada wrote:
> Why does it need to be a singleton method but can't a method from an included module?
I think this should work with arbitrary objects, and all objects in ruby that can have singleton classes support singleton methods. If you just want to deal with modules, you can currently do:
~~~
a1 = a.dup
(a.singleton_class.ancestors[1..-1] - a.class.ancestors).each do |m|
a1.extend m
end
a1.opts = a.opts.merge(hash).freeze
a1.freeze
~~~
However, there is no way to handle singleton methods AFAIK:
~~~
a.singleton_methods.each do |meth|
um = a.method(meth).unbind
# Raises TypeError
um.bind(a1)
end
~~~
In addition, doing dup/freeze instead of clone performs worse even if you are just copying modules. Here's a comparison using alternative approach #2 listed above. Code:
~~~
A = Struct.new(:opts) do
def initialize_clone(orig, opts={})
self.opts = orig.opts.merge(opts).freeze
super(orig)
end
def clone2(opts={})
clone = dup
(singleton_class.ancestors[1..-1] - self.class.ancestors).each do |m|
clone.extend m
end
clone.opts = self.opts.merge(opts).freeze
clone.freeze
end
end
module B; def b; 2 end end
module C; def c; 3 end end
a = A.new({})
a.extend B
a.extend C
def a.a; 1; end
a.freeze
h = {:a=>1}
require 'benchmark'
Benchmark.bm(15) do |x|
x.report('clone'){100000.times{a.clone(h)}}
x.report('dup/freeze'){100000.times{a.clone2(h)}}
end
~~~
Results:
~~~
user system total real
clone 2.210000 0.000000 2.210000 ( 2.209889)
dup/freeze 5.490000 0.000000 5.490000 ( 5.488063)
~~~
----------------------------------------
Feature #12092: Allow Object#clone to yield cloned object before freezing
https://bugs.ruby-lang.org/issues/12092#change-57506
* Author: Jeremy Evans
* Status: Feedback
* Priority: Normal
* Assignee: ruby-core
----------------------------------------
This allows creating modified clones of frozen objects that have
singleton classes:
~~~ruby
a = [1,2,3]
def a.fl; first + last; end
a.freeze
a.fl # => 4
clone = a.clone{|c| c << 10}
clone.last # => 10
clone.fl # => 11
clone.frozen? # => true
~~~
Previously, this was not possible at all. If an object was
frozen, the clone was frozen before the cloned object could
be modified. It was possible to modify the clone using
`initialize_clone` or `initialize_copy`, but you couldn't change how
to modify the clone on a per-call basis. You couldn't use `dup`
to return an unfrozen copy, modify it, and then freeze it, because
`dup` doesn't copy singleton classes.
This allows ruby to be used in a functional style with immutable
data structures, while still keeping the advantages of singleton
classes.
---Files--------------------------------
0001-Allow-clone-to-yield-cloned-object-before-freezing.patch (2.51 KB)
0001-Allow-clone-to-take-a-second-argument-passed-to-init.patch (2.37 KB)
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>