åå ã¯ã³ã³ããã¹ãã®æ¦å¿µãçºãã¦ãklassãç解ãããã¨ãå¿ è¦ã ã¨ãã話ã«ãªã£ãã®ã§ãã£ãã
klass
classæã®ä¸ã§ã¯æ§ç¯ãããã¨ãã¦ããã¯ã©ã¹ã«å¯¾å¿ããClassãªãã¸ã§ã¯ããselfã¨ãªã£ã¦ãããããã«ãclassæã®ä¸ã§ã®ã¯ã©ã¹ã¡ã½ããå®ç¾©ãã¿ãã¨ããªãã¨ãªãããããã©ã«ãã§ã¯selfã«ãæå®ããã°ãã®ãªãã¸ã§ã¯ãã«ãã¨ããã¡ã½ããå¼ã³åºãã«ãããã¬ã·ã¼ãã¼è§£æ±ºã«ä¼¼ã¦ããã
class Foo def self.class_method_hoge p :hoge end end class Bar def Foo.class_method_huga p :huga end def self.class_method_huga_of_bar p :huga end end
ãã®ãã¨ãèããã¨Rubyã§ã¯ãã¡ã½ããã¯selfã«å®ç¾©ãããã¨èããããªãããããã§ã¯ãªããå®ã¯ãããåã«ååã ã触ããklassã§ãããklassã¯æ£å¼ãªç¨èªã§ã¯ãªãããã®è¨äºã§ã¯ä»®ã«ããå¼ã¶ã¨ããã ãã§ãããäºç´èªclassã¨åºå¥ãããããã¾ãRubyå¦çç³»ã®ã½ã¼ã¹ãèªãã¨ã³ã³ããã¹ããåé¡ã«ãªããããã§ã¯klassã¨ããå¤æ°ã¯ãã®æå³ã§ãããã¨ãããä»®ã«klassã¨å¼ã¶ãã¨ã«ããã
Rubyã¬ãã«ã§ã¯è¡¨ã«ããããªããRubyå¦çç³»ã¯å é¨ã§ããã§ããklassã常ã«ä¿æãã¦ãããããã¯ãä»ã¡ã½ãããå®ç¾©ãããã©ãã«å®ç¾©ãããããã¨ããã¯ã©ã¹ã§ããããã®åå¨ãèããã¨Rubyææ³ã®ç解ããã£ããããã
ãããã¬ãã«ã§ã¯"main"ã¨å¼ã°ããããç¹å®ã®Objectã¤ã³ã¹ã¿ã³ã¹ãselfãªã®ã«ããããã¬ãã«ã§ã¡ã½ãããå®ç¾©ããã¨Objectã®ã¤ã³ã¹ã¿ã³ã¹ã¡ã½ããã«ãªããdefã®ä¸ã«æ´ã«defãæ¸ãã¨ããããã®defãå«ãã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ã¡ã½ããã«ãªããã¡ã½ããã¯ãselfã«å¯¾ãã¦ãå®ç¾©ãããããã§ã¯ãªãã®ã ã
ç§ã¯ã¯ããããããæ§è³ªãRubyã®éæ³ã ã¨æã£ã¦ããããä½ã®ãã¨ã¯ãªããè¦æè¦æã§ç確ã«klassãåãæ¿ãã¦ããã ãã§ããããããã¬ãã«ã§ã¯selfã¯mainã§ãklassã¯Objectã ãclassæã«å ¥ãã¨selfã¯æ§ç¯ä¸ã®ã¯ã©ã¹ã®Classãªãã¸ã§ã¯ãã«ãªããklassãåãã«ãªããdefã®ä¸ãè©ä¾¡ããã¨ãã¯(ã¡ã½ãããå®è¡ããã¨ãã¯)selfã¯ã¬ã·ã¼ãã¼ã§ãklassã¯ã¬ã·ã¼ãã¼ã®ã¯ã©ã¹ã§ããã
å¿è«ãããã°ã©ãã®ãã¼ãºãæãã¦ãã®ããã«Rubyãè¨è¨ããã¾ã¤ãã¨ããã®ãã¶ã¤ãã»ã³ã¹ã¯èª°ã«ã§ãçä¼¼ãã§ãããããªãã¨ã§ã¯ãªãã®ã ããã©ããã³ãã³ãã¹ã®åµã¨åãã§ä¸åè¦ã¦ãã¾ãã°ä½ã¨è¨ããã¨ã¯ãªãã
ã¡ã½ããå®ç¾©å ãã¬ã·ã¼ãã¼ã®è§£æ±ºã«ä¼¼ãã¦ããã®ã¯ãã¯ãããé¯è¦ãããããã§ããããæ®éã®classæãç¹ç°ã¡ã½ããå®ç¾©ããã¦ããéã¯ããé¯è¦ãã¦ããæ¹ãèããªããã°ãªããªãè¦ç´ ãå°ãªãã¦å¹¸ãã ãæ®æ®µã¯é¯è¦ãã¦ããæ¹ãè¯ãããinstance_evalãdefå defã®ãããªãã®ã絡ãã§ããã¨ãã«ã¯klassã®åå¨ãç¥ã£ã¦ããæ¹ãããã
åã³instance_eval
obj.instance_evalã¯objãselfã«ãã¦ãããã¯ãè©ä¾¡ããã®ã§ãã£ãããã®ã¨ããå®ã¯ããä¸ç¹ã³ã³ããã¹ããå¤æ´ããã¦ãããobj.instance_evalã¯objã®ç¹ç°ã¯ã©ã¹ãklassã«ãã¦ãããã¯ãè©ä¾¡ãããã¤ã¾ããinstance_evalå ã§ã¡ã½ãããå®ç¾©ããã¨objã®ç¹ç°ã¡ã½ããã«ãªãã
ããã§ã å¥æ²ã®ããã°ã©ã ã«ããinstance_evalå ã§å®éã«ã¡ã½ãããå®ç¾©ãã¦ã¿ã¦ã©ã®ã¯ã©ã¹ã«å®ç¾©ããã¦ããã®ããå¤å¥ãããå¯¾ç §ã¨ãã¦self, å®æ°, ã¯ã©ã¹å¤æ°ã®åç §ãããã³å®æ°, ã¯ã©ã¹å¤æ°ã®ä½æãè¡ãªã£ã¦ã¿ããçµæã¯æ¬¡ã®éãã
æåå | ã¡ã½ããå Proc | ã¯ã©ã¹å Proc | |
---|---|---|---|
self | #<Other:0x2349c> | #<Other:0x2344c> | #<Other:0x2344c> |
CONST | :other | :modified | :modified |
@@class | :other | :modified | :modified |
ã¡ã½ããä½æ | :singleton | :singleton | :singleton |
CONSTä½æ | :singleton | :not_defined | :original |
@@classä½æ | :other | :original | :original |
ç¸å¤ãããæååã®çµæã¯ãããããããå ¨é¨ãinstance_evalãä¸ããã³ã³ããã¹ãã«æã¾ã£ã¦ãããinstance_evalå ã§å®ç¾©ããã¡ã½ããã¯klassã«å¾ã£ã¦otherã®ç¹ç°ã¯ã©ã¹ã«æå±ãã¦ãããå®æ°ãotherã®ç¹ç°ã¯ã©ã¹ã«å±ããã¯ã©ã¹å¤æ°ã¯ã¡ãã£ã¨éããOtherã¯ã©ã¹ã«æå±ãã¦ãããããã¯æ©ãã ããã©ãã RHG ãè¦ããã¯ã©ã¹å¤æ°å®ç¾©å ãæ¢ãã¨ãã«ã¯ã¯é½åã«ããç¹ç°ã¯ã©ã¹ãã¹ãããããã¨æ¸ãã¦ãã£ãã
次ã«ãã¡ã½ããå ã§ä½æããProcã ããã¡ãã¯ã¡ã½ããå®ç¾©å ã¯klassã«å¾ãã®ã§ãã£ãããã®éãã«ãªã£ã¦ãããæ°ããä½ã£ãã¡ã½ããã¯otherã®ç¹ç°ã¯ã©ã¹ã«æå±ãã¦ããã
ä¸æ¹ãã¯ã©ã¹å¤æ°ã®å®ç¾©å ã¯å ã®ã³ã³ããã¹ããçãã¦ãããã¡ã½ããå ã§Procãä½æããå ´åãå®æ°ã«å¯¾ããä»£å ¥ã¯æ§æã¨ã©ã¼ãçãã¦ãã¾ãã®ã§è¨è¿°ã§ããªããå®ã¯ãå®æ°ãã¯ã©ã¹å¤æ°ã®è§£æ±ºã¯klassã¨ã¯å¥ã®æ©æ§ã§ãããªã表è¨ä¸ã®æ§é ã«ç¸ãããå½¢ã§ãããªããããã¯ã©ã¹å¤æ°ä»£å ¥ãOriginalã«å¯¾ãã¦è¡ããã¦ããã®ã¯ãã®ããã ã
ããã§ã代ããã«ä½¿ã£ãã®ãclassæã®ç´ä¸ã§ä½ã£ãProcã§ãããclassæã¯æå¾ã«è©ä¾¡ããå¼ãå¤ã¨ãã¦è¿ãã®ã§ãclassæã®æ»ãå¤ã使ãã°ããããProcãåå¾ã§ãã*1ããã¡ãã§ã¯å®æ°ä½æãè¨è¿°ã§ãã¦ãå®æ°ä½æå ã¯å ã®ã³ã³ããã¹ãã§ãããã¨ãåããã
ã¤ã¾ããobj.instance_evalã¯selfãobjã«ãã¡ã½ããå®ç¾©å klassãobjã®ãç¹ç°ã¯ã©ã¹ã«ãããã®ã§ãããã¨ã
åã³module_eval
ã§ãmodule_evalã¯instanc_evalã¨ã©ãéãã®ããããã¯ã¯ã©ã¹ã®ä¸ã«å ¥ã£ããã®ããã«æ¯ãèãã¡ã½ããã§ãããinstance_evalã¨åæ§ã« å¥æ²ã®ããã°ã©ã ãåããã¦ã¿ãã¨æ¬¡ã®ããã«ãªã£ãã
æåå | ~ã¡ã½ããå Proc | ~ã¯ã©ã¹å Proc | |
---|---|---|---|
self | Other | Other | Other |
CONST | :other_class | :modified | :modified |
@@class | :other | :modified | :modified |
ã¡ã½ããä½æ | :other | :other | :other |
CONSTä½æ | :other | :not_defined | :original |
@@classä½æ | :other | :original | :original |
ã¡ã½ããã®å®ç¾©å ã¯Otherã«ãªã£ã¦ãããmod.module_evalã¯selfãklassãmodã«ããæ¿ããã®ã§ããã
使ãåã
ã§ããããªå¾®å¦ãªéãã®ãã®ãã©ã使ãåããã®ããã¨ãã話ã
ãããã¯ä»ãmodule_evalã¯ã»ã¨ãã©ããå¤å´ã®ãã¼ã«ã«å¤æ°ãåç §ã§ããclassæããã ãæ°è¦ã¯ã©ã¹ãä½æãããã¨ã¯ã§ããªããã§ããã *2 ã¯ã©ã¹ãå¼ãã®ãç®çãªãmodule_evalã使ã£ãæ¹ãéåæããªãã¯ãã ã
Classã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ã«å¯¾ãã¦instance_evalãå¼ãã§ããã¯ããã¯ã©ã¹å®ç¾©æã¨ã¯éããæ®éã®ã¯ã©ã¹å®ç¾©æãªãklassã¯Classã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ãã®ãã®ã«ãªã£ã¦ããããinstance_evalå ã§ã¯ãã®ç¹ç°ãªãã¸ã§ã¯ããã¤ã¾ããã¡ã¿ã¯ã©ã¹ã«ãªã£ã¦ããããã ã
class Foo; end Foo.instance_eval do def hoge p :ok end end foo = Foo.new foo.hoge # => undefined method `hoge' for #<Foo:0x25580> (NoMethodError)
ãã®ç¹ãmodule_evalãªãã¯ã©ã¹ãåãªã¼ãã³ããã¨ãã¨åãããã«æ°è»½ã«ä½¿ãã¦ããããå¤å´ã®ã¹ã³ã¼ãã®ãã¼ã«ã«å¤æ°ãåç §ã§ããã
ä¸æ¹ãç¹å®ã®ãªãã¸ã§ã¯ãã«ã ã注ç®ãã¦æä½ããããªããã¯ãinstance_evalã便å©ã ãã¡ã½ãããå®ç¾©ããã°ããã©ã«ãã§ç¹ç°ã¡ã½ããã«ãªãã¨ããæ§è³ªã¯å½±é¿ããã®ãªãã¸ã§ã¯ãããå¤ã«æ¼ããªãã¨ãããã¨ãªã®ã§å¬ããã
ã¾ããRubyã§ã¯ã¯ã©ã¹ããªãã¸ã§ã¯ããªã®ã§çµå±åããããªãã¨ããããã¨æãã°ã§ããã®ã ãããã¯ã©ã¹ããªãã¸ã§ã¯ãã§ãã£ã¦ã¯ã©ã¹ã®ç¹ç°ã¯ã©ã¹ãã¡ã¿ã¯ã©ã¹ã§ãã¨ããããã¨ãå¿ããã¾ã¾æä½ããã«ã¯ãã¯ã©ã¹ã«ã¯module_evalããã以å¤ã«ã¯instance_evalãã ããã®ããããæèããªããã°ãªããªãå¤ãªæä½ãããã¨ãã¯ãä»æ¹ããªããä¸ã®è¡¨ãç¨ã¿ãªããããã°ããã
define_method
Module#define_methodã¯Procãåãåãã¨ãããå ã«ã¡ã½ãããå®ç¾©ãã¦ãããã®ã§ãã£ãããã®ã¡ã½ãããå¼ã³åºãã°ãProcå ã®ã³ã¼ããå®è¡ããã¨ãã®selfã¯ã¡ã½ããã®ã¬ã·ã¼ãã«ãªã£ã¦ãã *3 ãã ãããdefine_methodãã¾ãselfå·®ãæ¿ãç³»ã®ã¡ã½ããã§ããã¨è¨ããªãããªãã
ä¾ã«ãã£ã¦ ãã¹ãããã°ã©ã ã§è©¦ãã¦ã¿ãã
ã¡ã½ããå Proc | ã¯ã©ã¹å Proc | |
---|---|---|
caller | ["define_method.rb:49:in `call'", "define_method.rb:122"] | ["define_method.rb:49:in `call'", "define_method.rb:124"] |
self | #<Other:0x22c2c @instance=:other> | #<Other:0x22c2c @instance=:other> |
__FILE__ | "define_method.rb" | "define_method.rb" |
__LINE__ | 14 | 98 |
CONST | :modified | :modified |
$global | :other | :other |
@@class | :modified | :modified |
@instance | :other | :other |
local | :original | :class |
ã¡ã½ããä½æ | :other | :other |
CONSTä½æ | :not_defined | :original |
@@classä½æ | :original | :original |
- callerãè¦ãã¨ãä½æãããã¡ã½ããã®å®ç¾©ä½ç½®ã¯define_methodã®å¼ã³åºãä½ç½®ã«ãªã£ã¦ããã
- selfã¯å·®ãæ¿ãã£ã¦ãã
- FILE, LINEã¯Procä½ææã®ã¾ã¾ä¿ããã¦ããããã ã
localå¤æ°ã¯å ã®ã³ã³ããã¹ããçãã¦ãããåã«ãè¿°ã¹ãããdefine_methodã«ãã£ã¦closureã§ããã¡ã½ãããä½æã§ããã®ã§ããã
ããã§å¤æ°åã®è¡çªãåé¿ããã¨ãããã¿ã話ããããã©ããç§ãã½ãã½ããã¦ããéã«ã¾ã¤ãã¨ããã class local instance variable ãå®è£ ãã¦ãã¾ã£ãã®ã§1.9ã§ã¯ããã§æ¸ãããã
æ°è¦ã¡ã½ããä½æãè¦ãã¨klassã¯å·®ãæ¿ãã£ã¦ãããã¨ãåããã
- CONST, @@class, CONSTä½æ, ã¯ã©ã¹å¤æ°ä½æãè¦ãã¨Procä½ææã®ä½ç½®ã«å¾ã£ã¦ããããã¯ããããã®ååã®è§£æ±ºã¯klassã¨ã¯å¥ç©ãªã®ã ã
äºåã
éå ·ç«ã¦ã¯ããã£ããããã§ãããããç§ããããã®è¨äºãæ¸ããã¨æã£ããã£ããã®ãã¿ã«å ¥ãããé·ãåç½®ãã ãªã
ããããå ã¯ãã¯ãç§ãã©ãããç¾è±¡ãèµ·ããã®ãããåãã£ã¦ããªãã®ã§ãä¸åããã§postããã
*1: ããããææ³ã®ããã§ææ³å³ã¯ããããã¨ã«ãªã
*2:ã¡ãªã¿ã«ããå¤å´ã®ãã¼ã«ã«å¤æ°ãåç §ã§ããclassæããã ãæ¢åã®ã¯ã©ã¹ããªã¼ãã³ãããã¨ã¯ã§ããªãããClass.newã
*3:Ruby 1.6ã§ã¯éã£ããããã®å¤æ´ã§ç§ã¯1.8移è¡ã®ã¨ãã«çµæ§ã¯ã¾ã£ã