ã¢ããã¨ããè¨èã使ããã¨ãªã、ç´ç²é¢æ°åè¨èªã®å ¥åºåã解説ãã。Rubyã§ï½¡
ããã¯Ruby Advent Calendarã®21æ¥ç®ã®è¨äºã§ã*1。20æ¥ç®ã¯@sasata299ããã®Herokuって便利だし利用までたった3ステップですお!!ã§ãã。
ã¯ããã«
æ¬å½ã¯ãPure Rubyã§åããã£ãããå½¢æ
ç´ è§£æã¨ã³ã¸ã³ãã§ãã!!!ãã¿ãããªè¨äºãæ¸ãäºå®ã§ãããï½¤ç®æ¨ã®ã¯ãªãªãã£ã«éããªãã£ãã®ã§ãªãªã¼ã¹ã¯å»¶æããã¾ãã。
ã¯ãªã¹ãã¹ããã«ãªãªã¼ã¹ãããã¨ããã§ãã。
ãã¦ï½¤ãã®è¨äºã§ã¯ï½¤Haskellã®ãããªç´ç²é¢æ°åè¨èªãã©ã®ããã«å¯ä½ç¨ãä¼´ãå¦çãå®ç¾ãã¦ãããã«ã¤ãã¦ï½¤Rubyã«ããå®è£
ã使ã£ã¦è§£èª¬ãã¾ã。ã¢ããã¨ããè¨èãå
¨ãåºã¦ããªãã®ã§ã¢ã¬ã«ã®ã¼ã®ãããå®å¿ã§ãã。
ç´ç²é¢æ°ã¨ã¯
åã弿°ã渡ãéã、ã©ã®ãããªé çªã§ä½åº¦å¼ãã§ãåãçµæãè¿ããããªé¢æ°ã®ãã¨ã§ã。
ä½ãåé¡ãªã®ã
puts 'hello!' res1=gets puts 'hello!' res2=gets
ãã®ã³ã¼ãã«ããã、putsãgetsã¯ç´ç²é¢æ°ã§ã¯ããã¾ãã。
ãªããªã、
- putsã¯åã弿°ã§å¼ã°ãã¦ãããï½¤çµæãåãã¨ã¯éããªã(ãã¤ããå£ãã¦ãããã¨ã©ã¼ã«ãªããã)
- getsã¯å¼æ°ãªãã§2åå¼ã°ãã¦ããã、ã¦ã¼ã¶å ¥åã«ãã£ã¦è¿ãå¤ã¯å¤ãã
ããã§ã。
ã§ã¯ï½¤ç´ç²ãªé¢æ°ã使ç¨ãã¦å ¥åºåãå®ç¾ããã«ã¯ã©ããããããã®ã§ãããã。
ç´ç²ã«ãã(ãããã)
def dirty_greet puts 'èåã¯?' last_name=gets puts 'ååã¯?' first_name=gets puts "ããã«ã¡ã¯ï½¤#{last_name.strip} #{first_name.strip}ãã!" end
> dirty_greet èåã¯? ã¾ã¤ã㨠ååã¯? ããã²ã ããã«ã¡ã¯ï½¤ã¾ã¤ã㨠ããã²ããã! => nil
dirty_greet颿°ã¯ï½¤å
é¨ã§ç´ç²ã§ãªã颿°ãå¼ãã§ããã®ã§ç´ç²ã§ã¯ããã¾ãã。
ããã¨åçã®å¦çãç´ç²é¢æ°ã§å®ç¾ããã«ã¯ã©ããããããã§ããã。
ç´ç²é¢æ°ã¨ã¯ï½¤åã弿°ã§ä½åº¦å¼ãã§ãåãçµæãè¿ã颿°ã®ãã¨ã§ãã。å¯ä½ç¨ã®ãããã¹ã¦ã®é¢æ°ã«å¯¾ãã¦ï½¤åã弿°ã§å¼ã¶ã®ã¯ä¸åº¦ããã¨ããå¶éãä»ãããã©ããªãã§ããã。ãã¨ãã°ï½¤å¼ã¶ãã³ã«é£çªã渡ãã¨ã:
def manual_pure_gets seq gets end a=manual_pure_gets 1 b=manual_pure_gets 2 # aã¨bãç°ãªã£ã¦ãè¯ã
颿°manual_pure_getsã¯ï½¤ç´ç²ã§ã!ã¨ããã、å¶éãå®ãéãç´ç²ãããªããã¨ããã¬ãªã!
å¯ä½ç¨ã®ãã颿°ãåã弿°ã§å¼ã¶ã®ã¯ä¸åº¦ããã¨ããå¶ç´ãå®ãã«ã¯ï½¤ãã®é¢æ°ã使ã£ã¦ããå´ã«ãç´°å·¥ãããå¿ è¦ãããã¾ã。
def double_gets [ manual_pure_gets(1), manual_pure_gets(2) ] end aa=double_gets bb=double_gets # aa,bbã¯ç°ãªãããç¥ããªãã®ã§ï½¤double_getsã¯ç´ç²ã§ã¯ãªã
def manual_pure_double_gets offset [ manual_pure_gets(offset+1), manual_pure_gets(offset+2) ] end aa=manual_pure_double_gets 1 bb=manual_pure_double_gets 4 # aa,bbãéã£ã¦ã弿°ãéãã®ã§ç´ç²
ãã³ã¶ã¼ã¤!!!
ã©ããªã«å¤§ããããã°ã©ã ã§ã、ãã®ããããã§ã©ãã«ããªãããã§ãã
æ´ç·´ããã
ããã、ããããªãã§ãããã¯é¢åã§ã。é£çªããã¾ãæ±ãããã«ï½¤é¢æ°ã®æ»ãå¤ã¨ãã¦ã次ã®çªå·ãã追å ã§è¿ãããã«ãã¦ã¿ã¾ã。
# ããã¯ãããã°ãã°ç¨ã®é¢æ°ãªã®ã§ç´ç²ãããªãã¦ããããã§ã。 def enter method_name,*args puts " ENTER: #{method_name}(#{args.map(&:inspect).join(', ')})" end def s_pure_gets seq enter 's_pure_gets',seq line=gets # ãæ¬¡ã®çªå·ãã¨ãæ¬æ¥ã®å¤ãã®ãã¢ãè¿ã return [seq+1,line] end def s_pure_double_gets seq seq2,ret1=s_pure_gets seq seq3,ret2=s_pure_gets seq2 return [seq3,[ret1,ret2]] end seq1,aa=s_pure_double_gets 1 seq2,bb=s_pure_double_gets s1 # ç´ç²!
çªå·ã®ç®¡çãããªãã¦ããã®ã§ï½¤ãããæ¥½ã«ãªãã¾ãã。
ååã表示ããä¾ã¯ãããªãã¾ã:
def s_pure_puts str,seq enter 's_pure_puts',str,seq puts str return [seq+1,nil] end def s_pure_greet seq seq2 , _ = s_pure_puts 'èåã¯?',seq seq3 , last_name = s_pure_gets seq2 seq4 , _ = s_pure_puts 'ååã¯?',seq3 seq5 , first_name = s_pure_gets seq4 seq6 , _ = s_pure_puts "ããã«ã¡ã¯ï½¤#{last_name.strip} #{first_name.strip}ãã!",seq5 return [seq6,nil] end
> s_pure_greet 1 ENTER: s_pure_puts("èåã¯?", 1) èåã¯? ENTER: s_pure_gets(2) ã¾ã¤ã㨠ENTER: s_pure_puts("ååã¯?", 3) ååã¯? ENTER: s_pure_gets(4) ããã²ã ENTER: s_pure_puts("ããã«ã¡ã¯ï½¤ã¾ã¤ã㨠ããã²ããã!", 5) ããã«ã¡ã¯ï½¤ã¾ã¤ã㨠ããã²ããã! => [6, nil]
ããã£ãã§ãã。
ä¸èº«ãé ã
a=s_pure_gets 1 b=s_pure_gets 1 # ãã£ã¨!
ãå¯ä½ç¨ã®ãããã¹ã¦ã®é¢æ°ã¯åã弿°ã§äºåå¼ã°ãªããã¨ããã«ã¼ã«ãå®ãã®ã¯ï½¤ãªããªã大å¤ã§ã。ãã¡ãã¡é£çªã渡ãå¿ è¦ãããã¨ããã©ãããããã®ã§ï½¤ãã®ãããã®æ©æ§ãé è½ããããã®ã§ã。
# ããã§ï½¤ã¯ã©ã¹Pureãå°å ¥ãã¾ã。 class Pure # Pureã¯ã©ã¹ã¯ï½¤ãå®éã®å¦çããåãåãã³ã³ã¹ãã©ã¯ã¿ã¨ def initialize &body @body=body end # é£çªãåãåã£ã¦å®éã®å¦çãèµ·åï½¤çµæãè¿ãeffect!ã¡ã½ãããæã£ã¦ãã¾ã def effect! seq seq,ret=@body.call seq return [seq,ret] end end
ãé£çªãåãåã£ã¦æ¬¡ã®çªå·ã¨å¤ã®ãã¢ãè¿ããã¨ããæ§é ã、ããã§æ½è±¡åãããã¨ãããã。
def pure_puts str Pure.new {|seq| puts str; [seq+1,nil] } end def pure_gets Pure.new {|seq| line=gets; [seq+1,line] } end
pure_gets,pure_putsã¯seqã弿°ã¨ãã¦åãå¿ è¦ãããã¾ãã。ãããã®é¢æ°ã¯Pureãªãã¸ã§ã¯ããè¿ãã ã、å®éã®å ¥åºåã¯è¡ããªãã®ã§ç´ç²ãªãã§ã。
pure_ret=pure_gets # ãã®æç¹ã§ã¯å®éã®å¦çã¯è¡ãããªã pure_ret.effect! 1 # effect!ãå¼ãã æç¹ã§å¦çãå®è¡ããã
ã¦ã¼ã¶ãèªç±ãªå¼æ°ã§effect!ãå¼ã¶ã¨ç´ç²æ§ãç ´ç¶»ãã¦ãã¾ãã®ã§ï½¤ããªããPure.run!ãçµç±ããã«ã¼ã«ãä½ãã¾ã。
class Pure def self.run! pure pure.effect! 1 end end # ã¦ã¼ã¶ã¯é£çªãæèãããã¨ãªãå®è¡åºæ¥ã Pure.run! pure_gets
ã§ã¯ï½¤ãããã®é¢æ°ã§greet颿°ãä½ã£ã¦ã¿ã¾ããã。
def pure_greet pure_puts 'èåã¯?' pure_gets # => Pure {...} last_name=???? end
ãã£ã¨ï½¤ãã®ã¾ã¾ã§ã¯å ¥åãèªããã¨ãã§ãã¾ãã。å®éã«å ¥åãèªãã«ã¯effect!ã¡ã½ããã«é£çªã渡ãã¦ããå¿ è¦ãããã®ã§ãã、pure_greetå ã§ãããããã¨æ½è±¡åãå´©ãã¦ãã¾ã。
ããã§ï½¤Pureã¯ã©ã¹ãæ¡å¼µãã¦ï½¤ã次ã®å¦çããåæã§ããããã«ãã¾ã。
class Pure # ç¶ãã®å¦çãåæãã # contã¯ãªã«ãå¤ãåãåã£ã¦Pureãè¿ãProc def >> cont return Pure.new {|seq| seq2,ret=self.effect! seq cont_pure=cont.call(ret) cont_pure.effect! seq2 } end end
ããã使ãã°ï½¤Pureãçµã¿ç«ã¦ã¦å¤§ããªå¦çãä½ããã¨ãã§ãã。
readwrite = pure_gets >> # ä¸è¡èªãã§ï½¤ lambda{|line| pure_puts line} # ãã®å¤ã表示ãã Pure.run! readwrite
ããã¨ãããªãã¾ã
def pure_greet pure_puts('èåã¯?') >> lambda{|_| pure_gets } >> lambda{|last_name| pure_puts('ååã¯?') >> lambda{|_| pure_gets } >> lambda{|first_name| pure_puts("ããã«ã¡ã¯ï½¤#{last_name.strip} #{first_name.strip}ãã!") } } end
# pure_puts,pure_getsã«ãã°åºåã追å ãã¦ããã¾ã def pure_puts str enter 'pure_puts',str Pure.new {|seq| enter 'pure_puts[Pure]',seq; puts str; [seq+1,nil] } end def pure_gets enter 'pure_gets' Pure.new {|seq| enter 'pure_gets[Pure]',seq;line=gets; [seq+1,line] } end Pure.run! pure_greet
> Pure.run! pure_greet ENTER: pure_puts("èåã¯?") ENTER: pure_puts[Pure](1) èåã¯? ENTER: pure_gets() ENTER: pure_gets[Pure](2) ã¾ã¤ã㨠ENTER: pure_puts("ååã¯?") ENTER: pure_puts[Pure](3) ååã¯? ENTER: pure_gets() ENTER: pure_gets[Pure](4) ããã²ã ENTER: pure_puts("ããã«ã¡ã¯ï½¤ã¾ã¤ã㨠ããã²ããã!") ENTER: pure_puts[Pure](5) ããã«ã¡ã¯ï½¤ã¾ã¤ã㨠ããã²ããã! => [6, nil]
ã¤ã¨ã¤!
æå¾ã®1ãã¼ã¹
ã¦ã¼ã¶ã«ä½ããå°ããpure_prompt颿°ãå®ç¾©ã、å¦çã®éè¤ãæ¸ããã¦ã¿ã¾ããã。
def pure_prompt message pure_puts(message) >> lambda{|_| pure_gets }>> lambda{|line| line.strip } # ãã£ã¨ end def pure_greet2 pure_prompt('èåã¯?') >> lambda{|last_name| pure_prompt('ååã¯?') >> lambda{|first_name| pure_puts "ããã«ã¡ã¯ï½¤#{last_name} #{first_name}ãã!" } } end
ããã、ãã®ã³ã¼ãã¯åãã¾ãã。Pureã¨åæããlambdaã¯Pureãè¿ãå¤ã¨ãã¦è¿ããã°ãªããªãã®ã«ï½¤pure_promptã®æå¾ã®å¦çã§ã¯æååãè¿ãã¦ãã¾ã。
ãµã¤ãã®å¤ãPureã«å¤æããå¦çããã£ããããã§ãã。
class Pure def self.ret value return Pure.new {|seq| [seq,value]} end end def pure_prompt message enter 'pure_prompt',message pure_puts(message) >> lambda{|_| pure_gets }>> lambda{|line| Pure.ret line.strip } # StringãPureã«å¤æãã end def pure_greet2 pure_prompt('èåã¯?') >> lambda{|last_name| pure_prompt('ååã¯?') >> lambda{|first_name| pure_puts "ããã«ã¡ã¯ï½¤#{last_name} #{first_name}ãã!" } } end Pure.run! pure_greet2
> Pure.run! pure_greet2 ENTER: pure_prompt("èåã¯?") ENTER: pure_puts("èåã¯?") ENTER: pure_puts[Pure](1) èåã¯? ENTER: pure_gets() ENTER: pure_gets[Pure](2) ã¾ã¤ã㨠ENTER: pure_prompt("ååã¯?") ENTER: pure_puts("ååã¯?") ENTER: pure_puts[Pure](3) ååã¯? ENTER: pure_gets() ENTER: pure_gets[Pure](4) ããã²ã ENTER: pure_puts("ããã«ã¡ã¯ï½¤ã¾ã¤ã㨠ããã²ããã!") ENTER: pure_puts[Pure](5) ããã«ã¡ã¯ï½¤ã¾ã¤ã㨠ããã²ããã! => [6, nil]
ã¾ã¨ã
- ãªããç´ç²é¢æ°ã§IOã§ãã¦ãã¾ãã¾ãã!!!
- ã¢ããã¨ããååãã§ã¦ããªãã£ã
- æ¬å½ã«åã£ã¦ãã®ãããããªããªã£ã¦ããâ¦â¦ ééã£ã¦ããã誰ããææãã¦ããããã¨ãä¿¡ãã¦ãã¾ãâ¦â¦
- é£çªã¯ãã°ãã ããã¨ããæ°ã
- ã§ããä¸çã®ç¶æ ãã«å¤ãã¦ãå ¨ç¶è§£èª¬å¤ãããªãæ°ããããã§ããã
*1:ããæ¥ä»å¤ãã£ããã©