%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /proc/self/root/opt/cpanel/ea-ruby24/root/usr/share/ri/system/syntax/
Upload File :
Create Path :
Current File : //proc/self/root/opt/cpanel/ea-ruby24/root/usr/share/ri/system/syntax/page-refinements_rdoc.ri

U:RDoc::TopLevel[	iI"syntax/refinements.rdoc:EFcRDoc::Parser::Simpleo:RDoc::Markup::Document:@parts[^S:RDoc::Markup::Heading:
leveli:	textI"Refinements;To:RDoc::Markup::BlankLineo:RDoc::Markup::Paragraph;[	I"RDue to Ruby's open classes you can redefine or add functionality to existing ;TI"Qclasses.  This is called a "monkey patch".  Unfortunately the scope of such ;TI"Lchanges is global.  All users of the monkey-patched class see the same ;TI"Nchanges.  This can cause unintended side-effects or breakage of programs.;T@
o;
;[I"ORefinements are designed to reduce the impact of monkey patching on other ;TI"Ousers of the monkey-patched class.  Refinements provide a way to extend a ;TI"class locally.;T@
o;
;[I" Here is a basic refinement:;T@
o:RDoc::Markup::Verbatim;[I"
class C
;TI"  def foo
;TI"    puts "C#foo"
;TI"  end
;TI"	end
;TI"
;TI"module M
;TI"  refine C do
;TI"    def foo
;TI"      puts "C#foo in M"
;TI"
    end
;TI"  end
;TI"	end
;T:@format0o;
;[I"PFirst, a class +C+ is defined.  Next a refinement for +C+ is created using ;TI"RModule#refine.  Refinements only modify classes, not modules so the argument ;TI"must be a class.;T@
o;
;[I"LModule#refine creates an anonymous module that contains the changes or ;TI"Srefinements to the class (+C+ in the example).  +self+ in the refine block is ;TI"9this anonymous module similar to Module#module_eval.;T@
o;
;[I")Activate the refinement with #using:;T@
o;;[
I"
using M
;TI"
;TI"c = C.new
;TI"
;TI"!c.foo # prints "C#foo in M"
;T;0S;	;
i;I"
Scope;T@
o;
;[	I"PYou may activate refinements at top-level, and inside classes and modules. ;TI"RYou may not activate refinements in method scope.  Refinements are activated ;TI"Runtil the end of the current class or module definition, or until the end of ;TI"/the current file if used at the top-level.;T@
o;
;[I"QYou may activate refinements in a string passed to Kernel#eval. Refinements ;TI"+are active the end of the eval string.;T@
o;
;[I"SRefinements are lexical in scope.  Refinements are only active within a scope ;TI"Tafter the call to using. Any code before the using statement will not have the ;TI"refinement activated.;T@
o;
;[I"RWhen control is transferred outside the scope the refinement is deactivated. ;TI"TThis means that if you require or load a file or call a method that is defined ;TI"Boutside the current scope the refinement will be deactivated:;T@
o;;[I"
class C
;TI"	end
;TI"
;TI"module M
;TI"  refine C do
;TI"    def foo
;TI"      puts "C#foo in M"
;TI"
    end
;TI"  end
;TI"	end
;TI"
;TI"def call_foo(x)
;TI"
  x.foo
;TI"	end
;TI"
;TI"
using M
;TI"
;TI"x = C.new
;TI"'x.foo       # prints "C#foo in M"
;TI"*call_foo(x) #=> raises NoMethodError
;T;0o;
;[I"SIf a method is defined in a scope where a refinement is active the refinement ;TI"Rwill be active when the method is called.  This example spans multiple files:;T@
o;
;[I"
c.rb:;T@
o;;[I"
class C
;TI"	end
;T;0o;
;[I"
m.rb:;T@
o;;[I"require "c"
;TI"
;TI"module M
;TI"  refine C do
;TI"    def foo
;TI"      puts "C#foo in M"
;TI"
    end
;TI"  end
;TI"	end
;T;0o;
;[I"m_user.rb:;T@
o;;[I"require "m"
;TI"
;TI"
using M
;TI"
;TI"class MUser
;TI"  def call_foo(x)
;TI"    x.foo
;TI"  end
;TI"	end
;T;0o;
;[I"
main.rb:;T@
o;;[I"require "m_user"
;TI"
;TI"x = C.new
;TI"m_user = MUser.new
;TI".m_user.call_foo(x) # prints "C#foo in M"
;TI"1x.foo              #=> raises NoMethodError
;T;0o;
;[I"HSince the refinement +M+ is active in <code>m_user.rb</code> where ;TI"C<code>MUser#call_foo</code> is defined it is also active when ;TI"+<code>main.rb</code> calls +call_foo+.;T@
o;
;[I"TSince #using is a method, refinements are only active when it is called.  Here ;TI"Aare examples of where a refinement +M+ is and is not active.;T@
o;
;[I"In a file:;T@
o;;[I"# not activated here
;TI"
using M
;TI"# activated here
;TI"class Foo
;TI"  # activated here
;TI"  def foo
;TI"    # activated here
;TI"  end
;TI"  # activated here
;TI"	end
;TI"# activated here
;T;0o;
;[I"In a class:;T@
o;;[I"# not activated here
;TI"class Foo
;TI"  # not activated here
;TI"  def foo
;TI"    # not activated here
;TI"  end
;TI"  using M
;TI"  # activated here
;TI"  def bar
;TI"    # activated here
;TI"  end
;TI"  # activated here
;TI"	end
;TI"# not activated here
;T;0o;
;[I"QNote that the refinements in M are not activated automatically if the class ;TI"Foo is reopened later.;T@
o;
;[I"
In eval:;T@
o;;[I"# not activated here
;TI"eval <<EOF
;TI"  # not activated here
;TI"  using M
;TI"  # activated here
;TI"	EOF
;TI"# not activated here
;T;0o;
;[I"When not evaluated:;T@
o;;[
I"# not activated here
;TI"if false
;TI"  using M
;TI"	end
;TI"# not activated here
;T;0o;
;[I"RWhen defining multiple refinements in the same module, inside a refine block ;TI"Nall refinements from the same module are active when a refined method is ;TI"called:;T@
o;;[I"module ToJSON
;TI"  refine Integer do
;TI"    def to_json
;TI"      to_s
;TI"
    end
;TI"  end
;TI"
;TI"  refine Array do
;TI"    def to_json
;TI"7      "[" + map { |i| i.to_json }.join(",") + "]"
;TI"
    end
;TI"  end
;TI"
;TI"  refine Hash do
;TI"    def to_json
;TI"N      "{" + map { |k, v| k.to_s.dump + ":" + v.to_json }.join(",") + "}"
;TI"
    end
;TI"  end
;TI"	end
;TI"
;TI"using ToJSON
;TI"
;TI"Ap [{1=>2}, {3=>4}].to_json # prints "[{\"1\":2},{\"3\":4}]"
;T;0S;	;
i;I"Method Lookup;T@
o;
;[I"GWhen looking up a method for an instance of class +C+ Ruby checks:;T@
o:RDoc::Markup::List:
@type:BULLET:@items[	o:RDoc::Markup::ListItem:@label0;[o;
;[I"QIf refinements are active for +C+, in the reverse order they were activated:;To;;;;[o;;0;[o;
;[I"6The prepended modules from the refinement for +C+;To;;0;[o;
;[I"The refinement for +C+;To;;0;[o;
;[I"5The included modules from the refinement for +C+;To;;0;[o;
;[I"!The prepended modules of +C+;To;;0;[o;
;[I"+C+;To;;0;[o;
;[I" The included modules of +C+;T@
o;
;[I"QIf no method was found at any point this repeats with the superclass of +C+.;T@
o;
;[
I"INote that methods in a subclass have priority over refinements in a ;TI"Lsuperclass.  For example, if the method <code>/</code> is defined in a ;TI"Mrefinement for Integer <code>1 / 2</code> invokes the original Fixnum#/ ;TI"Tbecause Fixnum is a subclass of Integer and is searched before the refinements ;TI" for the superclass Integer.;T@
o;
;[I"QIf a method +foo+ is defined on Integer in a refinement, <code>1.foo</code> ;TI">invokes that method since +foo+ does not exist on Fixnum.;T@
S;	;
i;I"+super+;T@
o;
;[I"2When +super+ is invoked method lookup checks:;T@
o;;;;[o;;0;[o;
;[I"QThe included modules of the current class.  Note that the current class may ;TI"be a refinement.;To;;0;[o;
;[I"PIf the current class is a refinement, the method lookup proceeds as in the ;TI"!Method Lookup section above.;To;;0;[o;
;[I"QIf the current class has a direct superclass, the method proceeds as in the ;TI"6Method Lookup section above using the superclass.;T@
o;
;[I"MNote that +super+ in a method of a refinement invokes the method in the ;TI"Srefined class even if there is another refinement which has been activated in ;TI"the same context.;T@
S;	;
i;I"Indirect Method Calls;T@
o;
;[I"MWhen using indirect method access such as Kernel#send, Kernel#method or ;TI"RKernel#respond_to? refinements are not honored for the caller context during ;TI"method lookup.;T@
o;
;[I"0This behavior may be changed in the future.;T@
S;	;
i;I"Further Reading;T@
o;
;[I"USee https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/RefinementsSpec for the ;TI"Qcurrent specification for implementing refinements.  The specification also ;TI"contains more details.;T:
@file@:0@omit_headings_from_table_of_contents_below0

Zerion Mini Shell 1.0