[#46105] [ruby-trunk - Feature #6687][Open] Enumerable#with — "merborne (kyo endo)" <redmine@...>

14 messages 2012/07/02

[#46133] [ruby-trunk - Feature #6688][Open] Object#replace — "prijutme4ty (Ilya Vorontsov)" <prijutme4ty@...>

24 messages 2012/07/03

[#46160] [ruby-trunk - Feature #6693][Open] Don't warn for unused variables starting with _ — "marcandre (Marc-Andre Lafortune)" <ruby-core@...>

15 messages 2012/07/04

[#46200] [ruby-trunk - Bug #6702][Open] Date should be either required or not — "rosenfeld (Rodrigo Rosenfeld Rosas)" <rr.rosas@...>

14 messages 2012/07/05

[#46296] [ruby-trunk - Feature #6717][Open] Method like #instance_eval that returns self (like #tap) — "alexeymuranov (Alexey Muranov)" <redmine@...>

10 messages 2012/07/10

[#46320] [ruby-trunk - Feature #6721][Open] Object#yield_self — "alexeymuranov (Alexey Muranov)" <redmine@...>

25 messages 2012/07/11

[#46339] [ruby-trunk - Bug #6724][Open] waaaaaaant! ( — "zenspider (Ryan Davis)" <redmine@...>

11 messages 2012/07/11

[#46377] [ruby-trunk - Feature #6727][Open] Add Array#rest (with implementation) — "duckinator (Nick Markwell)" <nick@...>

25 messages 2012/07/13

[#46492] [ruby-trunk - Feature #6737][Open] Add Hash#read and alias as #[]. — "trans (Thomas Sawyer)" <transfire@...>

12 messages 2012/07/15

[#46500] [ruby-trunk - Feature #6739][Open] One-line rescue statement should support specifying an exception class — Quintus (Marvin Gülker) <sutniuq@...>

22 messages 2012/07/15

[#46562] [ruby-trunk - Feature #6758][Open] Object#sequence — "merborne (kyo endo)" <redmine@...>

19 messages 2012/07/20

[#46574] [ruby-trunk - Feature #6762][Open] Control interrupt timing — "ko1 (Koichi Sasada)" <redmine@...>

39 messages 2012/07/20

[#46641] [ruby-trunk - Bug #6780][Open] cannot compile zlib module, when cross-compiling. — "jinleileiking (lei king)" <jinleileiking@...>

14 messages 2012/07/23

[#46659] [ruby-trunk - Bug #6783][Open] Infinite loop in inspect, not overriding inspect, to_s, and no known circular references. Stepping into inspect in debugger locks it up with 100% CPU. — "garysweaver (Gary Weaver)" <garysweaver@...>

8 messages 2012/07/23

[#46792] [ruby-trunk - Bug #6799][Open] Digest::*.hexdigest returns an ASCII-8BIT String — "Eregon (Benoit Daloze)" <redmine@...>

11 messages 2012/07/26

[#46799] [ruby-trunk - Feature #6801][Open] String#~ for a here document — "merborne (kyo endo)" <redmine@...>

12 messages 2012/07/27

[#46829] [ruby-trunk - Feature #6806][Open] Support functional programming: forbid instance/class variables for ModuleName::method_name, allow for ModuleName.method_name — "alexeymuranov (Alexey Muranov)" <redmine@...>

7 messages 2012/07/28

[#46832] [ruby-trunk - Bug #6807][Open] Can't compile ruby without ruby — "devcurmudgeon (Paul Sherwood)" <storitel@...>

13 messages 2012/07/28

[#46834] [ruby-trunk - Feature #6808][Open] Implicit index for enumerations — "trans (Thomas Sawyer)" <transfire@...>

15 messages 2012/07/28

[#46838] [ruby-trunk - Bug #6810][Open] `module A::B; end` is not equivalent to `module A; module B; end; end` with respect to constant lookup (scope) — "alexeymuranov (Alexey Muranov)" <redmine@...>

17 messages 2012/07/28

[#46896] (Half-baked DRAFT) new `require' framework — SASADA Koichi <ko1@...>

Hi,

22 messages 2012/07/31

[ruby-core:46333] [ruby-trunk - Feature #6688] Object#replace

From: "prijutme4ty (Ilya Vorontsov)" <prijutme4ty@...>
Date: 2012-07-11 22:38:01 UTC
List: ruby-core #46333
Issue #6688 has been updated by prijutme4ty (Ilya Vorontsov).


shugo (Shugo Maeda) wrote:
> prijutme4ty (Ilya Vorontsov) wrote:
> > I suggest that #replace works not only on Enumerables but on any Object. It can make use the same object in different places more consistent.
> 
> Smalltalk has such a method called "become:", which swaps the receiver and the argument.
> For example:
> 
>   | x y z |
>   
>   x := 'foo'.
>   y := #(1 2 3).
>   z := y.
>   x become: y.
> 
>   ^ {x. y. z}  "=> #(#(1 2 3) 'foo' 'foo')"
> 
> But I'm against your proposal.  become: is too dangerous because it breaks object identity.

`#become` is a good name
I can't understand your fears. Monkey patching is also too dangerous. I just propose that one could use all advantages of duck typing.
Imagine that you want to make method hash_with_indifferent_access! which not just create a new object but is also substituted instead of an old object. All structures which use old object will now unobtrusively use new object.
I can't understand why is this more dangerous than e.g. `def somefunc(arr); arr.shift; end`
When you give an array object that can be changed in method, you know what are you doing. If you don't want to change initial array - you just use somefunc(myarray.dup). Analogical you can write x.dup.became(y.dup) Certainly it makes nothing just like myarray.dup.shift or str.dup.upcase!
----------------------------------------
Feature #6688: Object#replace
https://bugs.ruby-lang.org/issues/6688#change-27952

Author: prijutme4ty (Ilya Vorontsov)
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 


I suggest that #replace works not only on Enumerables but on any Object. It can make use the same object in different places more consistent. It makes it possible to write
class Egg; end
class Hen; end
class HenHouse; attr_accessor :species; end
class Incubator; def incubate(egg) Hen.new; end

# Here it is!
class IncubatorWithReplace; 
  def incubate(egg) 
    egg.replace(Hen.new)
  end
end

e1,e2,e3 = Egg.new, Egg.new, Egg.new
h1, h2 = HenHouse.new, HenHouse.new

# One egg is shared between hen houses
h1.species = [e1, e2]
h2.species = [e1, e3]
p h1 # ==> <HenHouse @species = [#<Egg 1>,#<Egg 2>]
p h2 # ==> <HenHouse @species = [#<Egg 1>,#<Egg 3>]


 # First option. It's bad choise because it makes two "data structures" HenHouse inconsistent: 
 #   they have different object while must have the same
h1[0] = Incubator.new.incubate(h1[0])
p h1 # ==> <HenHouse @species = [#<Hen>,#<Egg 2>]
p h2 # ==> <HenHouse @species = [#<Egg 1>,#<Egg 3>]

 # Second option is ok - now both shared objects're changed.
IncubatorWithReplace.new.incubate(h1[0])
h1 # ==> <HenHouse @species = [#<Hen>,#<Egg 2>]
h2 # ==> <HenHouse @species = [#<Hen>,#<Egg 3>]  

 # Third option is bad - it wouldn't affect HenHouses at all
e1 = Incubator.new.incubate(e1)
p h1 # ==> <HenHouse @species = [#<Egg 1>,#<Egg 2>]
p h2 # ==> <HenHouse @species = [#<Egg 1>,#<Egg 3>]

 # while Fourth option is ok and works as second do
IncubatorWithReplace.new.incubate(e1) ## would affect both HenHouses
p h1 # ==> <HenHouse @species = [#<Hen>,#<Egg 2>]
p h2 # ==> <HenHouse @species = [#<Egg 1>,#<Egg 3>]


I can't imagine how it'd be realized, it looks like some dark magic with ObjectSpace needed to replace one object at a reference with another at the same reference. But I didn't found a solution.

About ret-value. I think it should be two forms:
Object#replace(obj, retain = false)
If retain is false #replace should return a reference to a new object (in fact the same reference as to old object but with other content)
If retain is true, old object should be moved at another place and new reference to it is returned, so:
e1 # ==> <Egg id:1>
e1.replace( Hen.new, true ) # ==> <Egg id:2>
e1 # ==> <Hen id:1>


-- 
http://bugs.ruby-lang.org/

In This Thread