[#33640] [Ruby 1.9-Bug#4136][Open] Enumerable#reject should not inherit the receiver's instance variables — Hiro Asari <redmine@...>

Bug #4136: Enumerable#reject should not inherit the receiver's instance variables

10 messages 2010/12/08

[#33667] [Ruby 1.9-Bug#4149][Open] Documentation submission: syslog standard library — mathew murphy <redmine@...>

Bug #4149: Documentation submission: syslog standard library

11 messages 2010/12/10

[#33683] [feature:trunk] Enumerable#categorize — Tanaka Akira <akr@...>

Hi.

14 messages 2010/12/12
[#33684] Re: [feature:trunk] Enumerable#categorize — "Martin J. Dst" <duerst@...> 2010/12/12

[#33687] Towards a standardized AST for Ruby code — Magnus Holm <judofyr@...>

Hey folks,

23 messages 2010/12/12
[#33688] Re: Towards a standardized AST for Ruby code — Charles Oliver Nutter <headius@...> 2010/12/12

On Sun, Dec 12, 2010 at 9:55 AM, Magnus Holm <judofyr@gmail.com> wrote:

[#33689] Re: Towards a standardized AST for Ruby code — "Haase, Konstantin" <Konstantin.Haase@...> 2010/12/12

On Dec 12, 2010, at 17:46 , Charles Oliver Nutter wrote:

[#33763] [Ruby 1.9-Bug#4168][Open] WeakRef is unsafe to use in Ruby 1.9 — Brian Durand <redmine@...>

Bug #4168: WeakRef is unsafe to use in Ruby 1.9

43 messages 2010/12/17

[#33815] trunk warnflags build issue with curb 0.7.9? — Jon <jon.forums@...>

As this may turn out to be a 3rd party issue rather than a bug, I'd like some feedback.

11 messages 2010/12/22

[#33833] Ruby 1.9.2 is going to be released — "Yuki Sonoda (Yugui)" <yugui@...>

-----BEGIN PGP SIGNED MESSAGE-----

15 messages 2010/12/23

[#33846] [Ruby 1.9-Feature#4197][Open] Improvement of the benchmark library — Benoit Daloze <redmine@...>

Feature #4197: Improvement of the benchmark library

15 messages 2010/12/23

[#33910] [Ruby 1.9-Feature#4211][Open] Converting the Ruby and C API documentation to YARD syntax — Loren Segal <redmine@...>

Feature #4211: Converting the Ruby and C API documentation to YARD syntax

10 messages 2010/12/26

[#33923] [Ruby 1.9-Bug#4214][Open] Fiddle::WINDOWS == false on Windows — Jon Forums <redmine@...>

Bug #4214: Fiddle::WINDOWS =3D=3D false on Windows

15 messages 2010/12/27

[ruby-core:33568] Re: [Ruby 1.9-Feature#4085][Open] Refinements and nested methods

From: Charles Oliver Nutter <headius@...>
Date: 2010-12-04 12:48:00 UTC
List: ruby-core #33568
Hello,

On Thu, Dec 2, 2010 at 9:42 PM, Yusuke ENDOH <mame@tsg.ne.jp> wrote:
> 2010/11/30 Charles Oliver Nutter <headius@headius.com>:
>> The global serial number approach in 1.9 means that any change that
>> flip that serial number cause all caches everywhere to invalidate.
>> Normally this only happens on method definition or module inclusion,
>> which is why defining methods or including modules at runtime is
>> strongly discouraged for performance reasons.
>
> Sorry I'm not sure that I could follow your argument about performance,
> so I may miss your point.
>
> I guess that casual users will execute all refinements immediately after
> program is started, like class definition and method definition.
> Thus, the global serial number approach will work well for refinement
> in main use cases, I think.
> In the sense, nested function by using refinements may be a problem.

For the main cases, I see it working this way:

* Parser sees "using" in a scope
* Child scopes will now be parsed as though they are refined
* VCALL, FCALL, CALL in child scopes are instead RVCALL, RFCALL, RCALL
** Likely other calls must be replaced/wrapped too, e.g. +=3D, []=3D,
[]+=3D, and so on. (messy!)
* Refined call versions check refinement first before checking
metaclass for target method

Maybe this helps make it clear why the refinement state of a given
scope must never be mutable...we want to be able to limit the extra
refinement checks to calls where refinements are active, leaving
unrefined calls as they are today.

>> And one last case that's a problem: author's intent. If I write a
>> block of code that does "1 + 1", I intend for that code to do normal
>> Fixnum#+, and I intend for the result to be 2. It should not be
>> possible for a caller to change the intent of my code just because I
>> passed it in a bock. This has been my argument against using blocks as
>> bindings, and it's another argument against instance_eval being able
>> to force refinments into "someone else's code".
>
> This is not a problem, but rather improvement. =C2=A0There is already ope=
n
> class which so often breaks your intent. =C2=A0Refinements may also break
> your intent, but it is less often and more controllable than open class.

Open classes break my intent globally and usually at boot time.
Refinement propagation into blocks is much more likely to break my
intent at some arbitrary time in the future, since refinements are
much more lazily applied than open class modifications. Lazy breakage
is always worse than eager breakage.

>> Now, some positive reinforcement for "using" being a keyword and
>> instance_eval not propagating refinements.
>
> I'm not against your proposal, but I wonder if it does not make sense
> because we can still write: eval("using FooExt")

eval is not a concern, because it always creates a new scope. If a
"using" is active, those scopes (or at least their child scopes) would
be statically marked as "refined", and my requirements are still met.

> To address your concern, `using' keyword should have a block:
>
> =C2=A0using FooExt
> =C2=A0 =C2=A0# FooExt enabled
> =C2=A0end
> =C2=A0# FooExt disabled
>
> I don't like this syntax because of more indentation, though.

I mention this at the bottom of my reply to Shugo...I'm uncomfortable
with "using" applying to the current scope and not just to child
scopes encountered after it. Once code begins executing against a
given scope, that scope's static state (like whether a refinement is
active) should never change. Given that "using" occurs only at
toplevel or in class/module bodies (i.e., during file load/require),
there's not as many concurrency concerns here. There are just a lot of
messy issues with "using" applying to the current scope:

* Does it affect calls that came before it?
* Do multiple "using" directives combine or overwrite each other?
* When pre-parsing or pre-compiling (AOT stuff), you would have to
walk the whole file looking for "using" to know how to emit compiled
results.

What we're really talking about with refinements is a way to lexically
say "make calls in these scopes do an extra indirection during
lookup." Unrefined calls should never have to perform this additional
indirection.

>> I can try to come up with a concrete example of the problems with the
>> current proposal and implementation, but the concurrency cases would
>> be difficult to show.
>
> I might find serious concurrency problem of Shugo's patch, though I'm
> not sure that this is what you mean. =C2=A0Indeed, we may have to give up
> propagating refinements via block.
>
> =C2=A0class C
> =C2=A0 =C2=A0def test; p :test; end
> =C2=A0end
> =C2=A0module FooExt
> =C2=A0 =C2=A0refine(C) { def test; p :foo; end }
> =C2=A0end
> =C2=A0module BarExt
> =C2=A0 =C2=A0refine(C) { def test; p :bar; end }
> =C2=A0end
> =C2=A0f =3D proc do
> =C2=A0 =C2=A0sleep 1
> =C2=A0 =C2=A0C.new.test
> =C2=A0end
> =C2=A0FooExt.class_eval(&f) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0#=3D> :foo (expected)
> =C2=A0BarExt.class_eval(&f) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0#=3D> :bar (expected)
> =C2=A0[ Thread.new { FooExt.class_eval(&f) }, =C2=A0#=3D> :foo (expected)
> =C2=A0 =C2=A0Thread.new { BarExt.class_eval(&f) } =C2=A0 #=3D> :foo (not =
expected)
> =C2=A0].each {|t| t.join }

Thank you, this helps illustrate the problems with modifying a block's
(formerly) static state. We really must not modify an
already-parsed/compiled scope with new refinements.

- Charlie

In This Thread