[#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:46338] [ruby-trunk - Feature #6688] Object#replace

From: "prijutme4ty (Ilya Vorontsov)" <prijutme4ty@...>
Date: 2012-07-11 23:24:49 UTC
List: ruby-core #46338
Issue #6688 has been updated by prijutme4ty (Ilya Vorontsov).


trans (Thomas Sawyer) wrote:
> =begin
> I don't think #replace works on Enumerables, rather it works on Array and Hash.
> 
> It does seem a rather powerful notion to be able to replace an object with another wherever is may be referenced. Though @shudo may be right that it is too dangerous. With good design, a proper interface can handle the reassignment through the usual mechanisms, although admittedly it may entail many more compute cycles to do it.
> 
> On the other hand, if Smalltalk supports it then perhaps it's worth consideration. Always respect the Smalltalk :) But I agree with it, better name is #become.  
> 
> Also note that a less dangerous notion of a generic replace is simply to copy common instance variables.
> 
>   class X
>     def initialize(a)
>       @a = a
>     end
>   end
> 
>   class Y
>     def initialize(a,b)
>       @a, @b = a, b
>     end
>   end
> 
>   x = X.new(1)
>   y = Y.new(2,3)
> 
>   x.a  #=> 1
>   x.replace(y)
>   x.a  #=> 2
> 
> Although a more appropriate name for this is probably #instance_replace. This preserves object identity, but can only be used to "copy" an object of the same type --which, if you think about it, is what Array#replace and Hash#replace does too actually.
> =end

Object copying is useful but far less powerful. Imagine that you want to redefine files ARGF is linked to. Instead of
ARGV = ['filename','filename2']; puts ARGF
you should write
ARGV.replace ['filename','filename2']; puts ARGF

But now imagine that you want to use lazy enumerator to print content of all files in a directory. You don't want to create an array of all files, so you just try to write 
`ARGV.replace Dir.to_enum(:glob,'**/*.txt'); puts ARGF`
...and fails because you can't use enumerable here, only an array. Why we should put up with it if it can be improved not to break duck-typing paradigm?
----------------------------------------
Feature #6688: Object#replace
https://bugs.ruby-lang.org/issues/6688#change-27955

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