On Lispã¨ãèªãã§Rubyã¨Lispã®éããã¡ãã£ã¨èãã
å ¨400ãã¼ã¸ã®ãã¡3/4ããã¯ãã®èª¬æã«å½ã¦ããã¦ãããPaul Grahamã®ãOn Lispãã8å²ã»ã©èªãã ãåé ã®Common Lispå ¥éã§ç´¹ä»ããã¦ããæ¨æºé¢æ°ãã¦ã¼ãã£ãªãã£é¢æ°ã®ãã¼ãã³ã°ã®ã²ã©ãï¼ãããã¨æ°åã§ãµãã£ãã¯ã¹ä»ããã¨ããrplacaã¨ãã£ã¦ã©ããï¼ï¼ããç ´å£çæä½ãããé¢æ°ã®æåã®ä¸çµ±ä¸æã«ãããããªãRubyã®ã»ããããããããï¼ãã¨ãæã£ãããwithç³»ãã¯ãããããªãã Rubyã®ãããã¯ã§ããããããã¨ãæã£ããããããã©ã確ãã«èªã¿é²ããã¨å ¨ç¶éãä¸çãå£éè¦ãã¦ããæ°ãããã
CLOSã®èª¬æã®å°å ¥ç·¨ã«å½ããã¨ããã§ãPaul Grahamã¯ç´ ã®Lispã®ä¸ã«ãªãã¸ã§ã¯ãã·ã¹ãã ãä½ã£ã¦ã¿ããããããæ³å以ä¸ã«ç°¡åãªè©±ã§ããããããªãã»ã©ãããã·ã¥ãã¼ãã«ã¨ã¯ãã¼ã¸ã£ãããã°ã大æµã®ãã¨ã¯ã§ããã®ã ã¨ãã¡ãã£ã¨é©ãããç¶æ¿ã®ã¢ãã«ã«ããã£ã¦ãã¡ã½ããã¨ãããã·ã³ãã«ã®ã«ãã¯ã¢ãããã©ããã©ããã¨ãã話ã ãããããåºæ¥ã¦å½ããåãã¨æããã ãã©ãOOè¨èªããããã¿ã¤ããã¼ã¹ãã¯ã©ã¹ãã¼ã¹ãå¤éç¶æ¿ãåä¸ç¶æ¿ã¨ããããããåé¡ãããã©ãããããããªã¨ã¼ã·ã§ã³ããã¹ã¦å®è¡å¹çã®å¦¥åãªãã«å®ç¾ã§ããã®ã ãããLispãä¸è¬çãªOOè¨èªã¨æ¯è¼ããã®ã¯ãããããééããªãã ããã
ä¾ãã°ãã¾ãRubyã§ã¯Ruby 2.0ã«åãã¦ãæ¢åã¯ã©ã¹ã¸ã®ã¢ã³ãã¼ãããã®å½±é¿åãéå®ãã¹ããã¹ã³ã¼ããéå®ããããmixinã®ã¨ãã«ååã®è¡çªããã£ãå ´åã®æåãå¤ãããã¨ãã¦ãããã©ãããããã®ã ã£ã¦ãCãããªãã¦ãLispã®ä¸ã«ãªãã¸ã§ã¯ãã·ã¹ãã ãä½ã£ã¦ãããããå®é¨ãå¤æ´ã¯ãã£ã¨å®¹æã ã£ãããããªãã ããããã¨æã£ããã¨ããããCRubyã®å ´åãCã®å£ãã³ããã権ã®å£ãåæã®å£ããã£ã¦ãããããå¤æ´ã¯æ¥µãã¦é£ãããã
On Lispå ¨ä½ãéãã¦æã£ããã©ãå¹çã«ã¤ãã¦å¸¸ã«è¨åããã£ã¦ãRubyãRailsã¨ãããéããªã¨æã£ããæè©®ãRuby/Railsãæåãã¦ãã®ã¯Webã¹ã¿ãã¯ãããã ããã¨æ¹å¤ããJavaã®çã¿ã®è¦ªã®ã¸ã§ã¼ã ã¹ã»ã´ã¹ãªã³ãããªããã©ã確ãã«æ±ç¨ããã°ã©ãã³ã°è¨èªã¨ãã¦ã¯Rubyã¯é ãã»ãã ãã2011å¹´ã®ä»ãRubyistã¨å¼ã°ãã人ã ã¯ãWebã¢ããªã°ããæ¸ãã¦ãããããã¾ãããã©ã¼ãã³ã¹ã®ãã¨ãè¨ããªãæ°ããããç¹ã«ã¡ã½ããå¼ã³åºãã®ãªã¼ãã¼ãããã¯ãå ¨ãç¡è¦ãã人ãå¤ãããããªãã ããããããããé åã§ããRubyã¯ä½¿ããã¦ãªãã®ãããããªãã
ãã1ã¤ãRubyã®ã³ã¢ã¯ã©ã¹ã使ã£ã¦ããã°å¹çã¯ãè¯ãã ãããã¨æ³å®ã§ããã£ã¦ãã¨ãããã®ãããå種ã¡ã½ããã¯Cããã«ã¼ã注ææ·±ãå®è£ ãã¦ãã¦ãã¢ã«ã´ãªãºã ãè¨ç®éã«ã¤ãã¦ããã¡ããã¨èãã¦ããã¦ããããã¨ãããããã¦ãæ¢åã®ã¯ã©ã¹ã©ã¤ãã©ãªã§è¶³ããªããã®ããã£ã¦ãèªåã§Common Lispã§ããã¨ããã®ãã¦ã¼ãã£ãªãã£é¢æ°ãã足ããããªããã¨ããã¨ãã©ããè¯ãåãããªããä»ã©ãã®è¨èªã¯æåããã¦ã¼ãã£ãªãã£é¢æ°ã¦ããçãã§ãã«ãã
ã¢ããã©ãªãã¯ãã¯ãã«ãã¡ãã£ã¨æåãããã¢ããã©ã©ã¨ããã®ã¯ãitãã®ããã«æ¢åºã®ä½ããæã示ãèªç¶è¨èªã®èªå½ããããå¿ç¨ãããaifãã¯ãifãã¨ã»ã¼åæ§ã®æåã ãã©ãifã®æ¡ä»¶ç¯ãè¿ãå¤ããitãã¨ããã·ã³ãã«ã«ãã¤ã³ããããããããã°RSpecã¨ãããRubyã®ã©ã¤ãã©ãªã§ãitãåºã¦ãããªã
(aif (big-long-calculation) (foo it))
ããã¯ãã¯ãã§å±éããã¦ã
(let ((it (big-long-calculation))) (if it (foo it) nil))
ã¨ãªãã以ä¸ã®ããã«ãã£ã¦ã¿ããEmacs Lispã§ãåãããæå³ã®ãªãã³ã¼ãã ãã©ã
(defmacro aif (test-form then-form &optional else-form) `(let ((it ,test-form)) (if it ,then-form ,else-form))) (defun double-if-odd (n) (if (oddp n) (* n 2))) (defun print-num (n) (aif (double-if-odd n) (message "%d" it))) (mapcar 'print-num '(1 2 3 4 5 6 7 8 9)) => ("2" nil "6" nil "10" nil "14" nil "18")
ãã1ã¤ãã¢ããã©ãªãã¯ãã¯ãã®ä¾ã¨ãã¦ã¯ãç¡åé¢æ°ã®å帰ã®ã¨ãã«ãã³ãã½ãªã¨selfã¨ããã©ãã«ãä»ãã¦ãå帰å¼ã³åºãã®ã¨ãã«ã(self hoge foo)ããªã©ã¨ãããã®ãé¢ç½ãã
ãã¯ãå±éã®å¾ã«ãæå³ããªãå½¢ã§å¤æ°ãè£è¶³ãã¦ãã¾ããã¨ããããã¦ããã®æ ¹æ¬çãªå¯¾çã¨ãã¦å¦çç³»ã«ã¦ãã¼ã¯ã§ãããã¨ãä¿è¨¼ããã·ã³ãã«ãçæãããä»çµã¿ãããã¨ããã®ã«ã¿ãã²ã¿ãããã«ã¯ãã®åé¡ãããããã®ããCommon Lispã«ã¯ãããããã¨ããã®ããã£ã¡ãã£ã¡ã«ãã£ã¦ãããã対ççæ³çã«æããããªãããªãããããªãã»ã©ãSchemerããããhygienic macroã¨ããã®ã¯ããã®åé¡ã®ãã¨ã ã£ãã®ããWikipediaã®è¨è¿°ã«ã¯ãHygienic transformationã¨ããæ¦ç¥ã«ãè¨åãããã
Rubyã§ã¢ããã©ãªãã¯ãªifã使ãããã©ãããã ãä¾ãã°ãRailsã®ã³ã¼ãããif.* =ãã§æ¤ç´¢ãã¦ã¿ããã以ä¸ã®ãããªç®æãããã
def redirect_to(options = {}, response_status_and_flash = {}) #:doc: if alert = response_status_and_flash.delete(:alert) flash[:alert] = alert end if notice = response_status_and_flash.delete(:notice) flash[:notice] = notice end if other_flashes = response_status_and_flash.delete(:flash) flash.update(other_flashes) end
ãããRubyã§ãaifããå®ç¾©ã§ãããããããã¯ã
def redirect_to(options = {}, response_status_and_flash = {}) #:doc: aif response_status_and_flash.delete(:alert) flash[:alert] = it end aif response_status_and_flash.delete(:notice) flash[:notice] = it end aif response_status_and_flash.delete(:flash) flash.update(it) end
ãªã©ã¨ãªããRailsã®ä¸ã§ã¯ããªãã·ã§ã³ã®ããã·ã¥ããç¹å®ã®ãªãã·ã§ã³æååãåãåºãã¨ããã³ã¼ãããããã¨ããã«ãã£ã¦ãããããã¨ããã¯ã
def _normalize_callback_options(options) if only = options[:only] only = Array(only).map {|o| "action_name == '#{o}'"}.join(" || ") options[:per_key] = {:if => only} end if except = options[:except] except = Array(except).map {|e| "action_name == '#{e}'"}.join(" || ") options[:per_key] = {:unless => except} end end
ã¨ãã風ã«ãªã£ã¦ããããããããaifã使ãã°ã
def _normalize_callback_options(options) aif options[:only] it = Array(it).map {|o| "action_name == '#{o}'"}.join(" || ") options[:per_key] = {:if => it} end aif options[:except] it = Array(it).map {|e| "action_name == '#{e}'"}.join(" || ") options[:per_key] = {:unless => it} end end
ã¨æ¸ãããã¨ããããããããoptionsã¨ããããã·ã¥ããåãåºããã¿ã¼ã³ããã¾ãã«ãå¤ãã®ã§ã
if some_option = options[:something] process some_option end
ã¯ã
ext-if options[:something] do process it end
ã¨ãæ¸ããã¨ããããããªãããããããããã¯ãã¯ãããªãã¦ãRubyã§å®ç¾©ã§ãããããããããããã£ã¦ãããã¯ã使ãã¨ããçºæ³ããã¯ãã«ããæ§æå¤æã®ã¬ãã«ã§ãã®ãã¨ãèãã¦ããªãã£ã¦ãã¨ãããã¯ãçãªèªç±åº¦ãããã°ã
ext-if { options[:something] : process it }
ã¨ãã
ext-if { options[:something] : ary << it}
ã¨ãã§ããã®ããªã
ãaifããRubyã§å®ç¾©ããã«ã¯ããããã¬ãã«ã«ã¡ã½ãããå ãããããªããæ¹ã§ã¯ãã¡ã§ãããã¯é¢æ°ã§ã¯å®ç¾©ã§ããªãããã¶ããparse.yãæ¸ãæãã¦Rubyã®ä¸èº«ã«æãå ¥ãããã¨ã«ãªããããã«ããããªãæé»çã«ãitããã³ã¼ãã«ç»å ´ããææ³ã£ã¦ã©ããã¨ããè°è«ãå½ç¶ããå¾ãã®ã§ããã®ææ³ãRubyã«å ¥ãå¯è½æ§ã¯æ¥µãã¦ä½ããã
æ°ããææ³ãå ¥ãããã¨ãããããã¡ãã£ã¨å¤æ çãªæåã®ææ³ãå ¥ããã«ãã¦ã¯ãå¾ãããå¹æãå°ããããã
ãªãã»ã©ãLispã«ã¯ããããå¶éããªããèªåèªèº«ããèªåã®ãã¼ã ãåæã§ãããªãããã®ç¨åº¦ã®æ¡å¼µã¯å¥ã«ä½ã¨ãããã¨ã¯ãªãããããªãã ãããã
ãRubyã¯åãå ¥ããããLispã ãã¨ãã主張ã®èæ¯ã«ã¯ãæ´»çºãªã³ãã¥ããã£ã«ããã©ã¤ãã©ãªéçºã®åã¿ãããï¼ããã¯ããã§ãRubyã®ã©ã¤ãã©ã©ãªã£ã¦Railsã®ä¼¼ããããªãã©ã°ã¤ã³ã¨ãã¹ãé¢é£ã°ã£ããã§ãå®ã¯åã¿ãªãããªãã¨ããæ¹å¤ãããããã ï¼ã
Hacker Newsã®このスレッドãèªãã¨ãã©ãããããã«ç»å ´ããRubyistãå£å¢ã«è¦ããããLispã«ããã§ããªãã¦Rubyã«ã§ããªããã¨ã£ã¦å ·ä½çã«ä½ï¼ å¹ç以å¤ã§ããã¨ããRubyã§ã¯å ¨ç¶Rubyã«è¦ããªãDSLãä½ããããããªé¢¨ã«ãã¨ãåè«ãã¦ããã©ãã©ããçå¤ãã®å°è±¡ãå¼·ãã
Lisperã®1人ã¯ã以ä¸ã®Rubyã®DSLã«ã¤ãã¦ããã¡ãã¡ã«Rubyã£ã½ããèªããããã¨è¨ã£ã¦ãã
get / 'orders' >> :orders > :index with route / :slug / 'order' >> :orders do get > :show put > :update end get {'item_images' => :controller} / :image > :show
ã¼ããããæããããã¯ãããªãéæ¿ãªã»ãã§ãä¸çå·ã®æ¼ç®åãªããã©ããã£ã¦å¦çãã¦ãã®ãæ°ã«ãªãã¨ããã ãã©ããã£ã±ãéæã«Rubyã£ã½ããããããRubyãæ¡å¼µãã¦ãããã¨ããæãã§ã¯ãªããã¨ããããRubyistã¯ããã®ã©ããRubyã£ã½ããã ã誰ããåã«åæããªãã¨æããã¨åè«ãã¦ãã¦ãè°è«ããã¿ãããªãããªãã»ã©ããã®è°è«ã®ããåãã«ã¤ãã¦ã¯Paul Grahamã®è¨ãã¨ãããããããªããããé«ãæ½è±¡ã¬ãã«ã§ç©äºãæãã¦ãã人ã¨ãããã§ãªã人ã¨ã§è°è«ããã¿ãããªãã®ã¯å½ç¶ã ã
ããããActiveSupportã«ãããActiveRecordã®DSLã«ãããã¯ã©ã¹ãæ¡å¼µããããæ¢åã¯ã©ã¹ã«ã´ãã§ã´ãã§ã£ã¨ã人éãèªã¿ä¸ããããã¡ã½ããã足ããããã¦ããã ãã§ãRubyãæ¡å¼µãªãã¦ãã¦ãªããã ãªãRubyãDSLã«åãã¦ããã¨è¨ãããã®ã¯ãèªã¿ä¸ããããèªå½ããã¤ãºãå°ãªã並ã¹ãããã¨ãããããã«çç±ãããããã ãã©ãããã¯å ã ãã¡ã½ããå¼ã³åºãæã«ã«ãã³ãçç¥ã§ããã ã¨ããããã·ã¥ã§ã·ã³ãã«ã渡ãã³ã³ãã³ã·ã§ã³ã ã¨ããããã¯Rubyãã®ãã®ãªããã ãã