Squareã«è»¢è·ãã¾ãã
11æããSquareã§åãã¦ãã¾ããPOSã¬ã¸ãä½ãã®ãå«ã«ãªã£ãã¨è¨ã£ã¦ã¦ãã¬ã¸ãè¾ãã¦Siderã«è»¢è·ããã®ã2016å¹´ããã®3å¹´å¾ã«ã¾ãã¬ã¸ã®ä¼ç¤¾ã§åããã¨ã«ãªãã¨ã¯â¦â¦ï¼ã¬ã¸ã¯ä½ã£ã¦ã¾ããããï¼ *1
ã¢ã¡ãªã«ã«è¡ãã®ãã¨ããã¨ãããªãã¨ã¯ãªãã¦ãæ±äº¬ã§æ¥æ¬æ³äººã®å¾æ¥å¡ã¨ãã¦åãã¦ãã¾ããSquareãæ¥æ¬ã§ãµã¼ãã¹éå§ããã®ã¯2013å¹´ã®ãã¨ã§ããããã以æ¥æ±äº¬ã®ãªãã£ã¹ã«ã¯éçºè ãããªãç¶æ³ã§ãããåéããã¦ãªãã£ãã®ã§ãããåéããããã©ããã®ç¢ºèªãããã«ç¥ãåãã¥ã¦ã«å¿åãã人éããã¦ããããç§ã§ãâ¦â¦å ¥ç¤¾ãã¦ããæ°ã¥ããã®ã§ãããæè¿ãå ¨ç¤¾ãæãã¦SFããä¸çä¸ã«åæ£ãã¦ããã¨ããã®ãé²ãã¦ããããã§ããã®æµãã«æ°ã¥ããªããã¡ã«ä¹ã£ã¦ããã®ããããã¾ããã
ä»åä»äºãæ¢ãã«å½ãã£ã¦ã¯ãRubyã¨Steepã®éçºã«æéã使ããããã«ããããã社å ã§Rubyã®åã«é¢ãããã¹ãã»å®é¨ããããã®ã§ããããªãã«äººæ°ããã¦Rubyã§æ¸ãããã³ã¼ãã«æè³ãç¶ãã¦ããææããããã¼ã ãã¨ããå¸æãããã¾ãããSquareã§ã¯ã
- æ±äº¬ãªãã£ã¹ã§çºçãã¦ããæ§ã ãªã¨ã³ã¸ãã¢ãªã³ã°ã«é¢ããåé¡ã®è§£æ±º
- Squareã®Rubyã³ã¼ãã¸ã®è²¢ç®ï¼åæ¤æ»ã¨ãï¼
- Ruby/Steepã®éçº
ãªã©ããã£ã¦ããã¨ãã話ã«ãªã£ã¦ãã¦ãã¤ã¾ãRubyã³ããã¿ã¨ãã¦ã給æã®ä¸é¨ãããã£ã¦ãããã¨ã«ãªãã®ã§ãããããã¯ãã¼ãã¿ã¤ã ã³ããã¿ãåä¹ã£ã¦ããããã¨æãã¾ãã
å ¥ç¤¾ã¾ã§ã®çµç·¯
å»å¹´Fog City Ruby Meetupã§Steepã®è©±ãããã¨ãã«ãShannonãBrandonãªã©Squareã®éçºè ã¨ä¼ã£ã¦ãã¦ããã以éãRubyConfãRubyKaigiãªã©ã§ä½åãé¡ãåããã¦ãããã¨ããããä»å¹´ã®å¤ã«è»¢è·ããããã¨æã£ãã¨ãã«ç¸è«ãã¦ã¿ãã®ããã£ããã§ãããã®å¾ã社å ã§èª¿æ´ãã¦ãããã®ã«å°ãæéãããã£ãããã§ãããé¢æ¥ãªã©ãã¦å ¥ç¤¾ã¨ãªãã¾ããã
é¢æ¥ã¯ã
- ã³ã¼ããæ¸ã
- ãã¯ã¤ããã¼ãã«ãçµµããããªããæè¡çãªè©±ããããã¤
- ããã¾ã§ã®çµé¨ãªã©ã«ã¤ãã¦è©±ããããã¤
ãªã©ã®ç¨®é¡ããã£ã¦ãæåã«ãªã¢ã¼ãã§1.ã¨3.ãä¸æéãã¤ã次ã«ã¾ããªã¢ã¼ãã§å ¨é¨ã§5æéãã¨ããæµãã ã£ãã¯ãã§ãã2ã©ã¦ã³ãç®ã®5æéã®æ¹ã¯ãå¤åæ®éã¯SFæ¬ç¤¾ã§ãããã ã¨æãã¾ãããç§ã®å ´åã¯ãªã¢ã¼ãã§3æ¥ããã¦ããã¾ãããã³ã¼ããæ¸ãã®ã¯ããé¡ãããã£ã¦å°ããªRubyããã°ã©ã ããã¢ããã°ã©ãã³ã°ãããã®ã§ãã¢ã«ã´ãªãºã ã«ã¤ãã¦è©³ããèããããã¨ãããæãã§ã¯ããã¾ããã§ããã*2
ä»ã®ã¨ããã®ææ³ãªã©
å ¥ç¤¾ãã¦1ã¶æããããªã®ã§ãã¾ã ã¾ã ããããã£ã¦ãªãã®ã§ããã
- ãããªãã«ã§ããä¼ç¤¾ãªã®ã§éçºè ãå¤ããCIãµã¼ãã¹ãèªåã®ãã®ã ã£ããããããã¨ç¤¾å åãã®ãã¼ã«ãããã£ã¦ããããããããã¨æè³ã§ãããã ãªã¼ã¨æã
- ã¢ã¡ãªã«ã¨ãã¼ãã£ã³ã°ããããã¨ãããã¾ããï¼ããã¼ã¸ã£ã¨ã®1 on 1ã¨ããéçºè ã¨ã®è©±ã¨ãï¼ãå°çã®å½¢ã®é½åããååä¸ã«ãããªä¼è°ã«ãªãã¾ã
- ããã¼ã¸ã£ããã¦ããããã¨ä¸è©±ãç¼ãã¦ãããã *3
ãªã©ãèå³æ·±ããããããããã¾ãã
ã¾ããWebãµã¤ãã®æ¡ç¨æ å ±ã¯ã¾ã åºã¦ããªãã®ã§ãããæ±äº¬ãªãã£ã¹ã§å¼ãç¶ãã¨ã³ã¸ãã¢ãæ¡ç¨ãã¦ããã¨ãã話ããã¦ãã¾ãã®ã§ãèå³ãããããã§ãããç§ã«å£°ãããã¦ããã ããã°ãç§ã¯Rubyãæ¸ãã¦ãã¾ããããã以å¤ã§ãJavaãiOSãAndroidãæ¸ããã°ããªãã¨ããªãã®ã§ã¯ãªããã¨æãã¾ãã
è±èªã¯ããªãå³ãããã¨ã¯ãã£ã¦è¦å´ã¯ããã¾ããããã¼ã¸ã£ã«ãããããã¤ã¯å°ãã ãã ãã©æ¥æ¬èªããããããããªã«ããã£ããç¸è«ãããã¨SFã§äººãç´¹ä»ãã¦ããã£ããã¨ãã1 on 1ã§åã£ã¦ã¦ããã¾ãéããªãã®ã§Slackã«æ¸ãã¦ããã£ããã¨ããç³ã訳ãªãæ°æã¡ãããâ¦â¦*4
*1:ã¡ãªã¿ã«ãåã¯æ¥æ¬ã§iPadåãã®POSã¬ã¸ãä½ã£ã¦ãããã ãã¨ç¤¾å ã§èªå·±ç´¹ä»ããã¨ã¾ãã¦ã±ã¾ãã
*2:ä¾ãã°Googleã§ã¯ããªãã¢ã«ã´ãªãºã ã®è©±ãçªã£è¾¼ãã§ããã¨èãã¦ãã¾ãããããã¨ã¯éãããã§ãã
*3:åã¯å¤§ä½ãã£ã¨ã¹ã¿ã¼ãã¢ããã®å½¹å¡ã¨ãã¦ä»äºããã¦ããã®ã§ãããã¼ã¸ã£ã«ç¸è«ãããåé¡ã解決ããã¨ããã®ã¯æ°é®®ãªä½é¨ã§ãã
*4:ä¸æ¹ã§ãæ¥æ¬èªã§è©±ãã¦ã¦ããã®ãããã®ææçéã®ã¨ã©ã¼ã¯ããã£ã¡ã ãã§ã¯ãã¨ããæããããã®ã§ãæ°æã¡ãå¼·ããã£ã¦çãã¦ããã¾ãã
TypeScriptã®anyã¿ãããªããªãã§ãä»£å ¥ã§ããåããåé¡ãã
å®å ¨ã§ãªããã® - void * (C)
ãããããããã ãããã©ãCããå§ããããvoid*
ã«ã¯ãªãã§ããã£ã¹ãã§ããããå
ã®åã«æ»ããã¨ãã§ãããã¾ãany
ãåé¡ã¯å¤ãªãã¨ããã£ãå ´åãï¼Cã¯ããããããªããã誰ããä¾ãæ¸ãã¦ãããï¼
ãã£ã¹ãã«ãã£ã¦å¤ãªåãå¾ãããå ´åã®æåã¯æªå®ç¾©ãªãã ã¨æããï¼ç¥ããªãããã誰ãä»æ§ã調ã¹ã¦ãããï¼æªå®ç¾©ã¨ããã®ã¯ãã³ã³ãã¤ã©ã¨ãè¨ç®æ©ã¯ä½ããã¦ãè¯ãã¨ããæå³ã§ã
- ããã»ã¹ã®å®è¡ãæ¢ãã
- æé©åã«ãã£ã¦ã³ã¼ããæ¶ãã
- ããã»ã¹ã®ã¡ã¢ãªãç ´å£ããªããåãç¶ãã
- é¼»ããæªéãåºã
ãªã©ã®ãã¿ã¼ã³ããããããå®éã«ã¯å¤§ä½SEGVã§è½ã¡ãã¨æããã ãã©ãããã¯ä»æ§ã«ã¯å«ã¾ãã¦ããªãã
ããã§ãå®å ¨ã§ãããã¨ããã®ã¯ãããã°ã©ã ã®å®è¡ä¸ã«æªå®ç¾©ã®ç¶æ ã«ãªããªããã¨ããæå³ã§ãããã¤ã¾ããCã¯å®å ¨ã§ã¯ãªãã
ãã£ã¹ãã®æ¤æ»ã§å®å ¨ã«ãªã£ããã® - dynamic (C#)
åçåä»ãã®è¨èªãæµè¡ã£ãããæ¬è³ªçã«åãæ¸ãã®ãå°é£ãªãã¿ã¼ã³ããããã¨ãå¤æããããã¦ãããã¤ãã®ããã°ã©ãã³ã°è¨èªã«ã¯ãã³ã³ãã¤ã«æã«åæ¤æ»ãããªãåãã¨ããã®ãå°å
¥ããããC#ã§è¨ãã¨ããã® dynamic
ã§ããã
string x = ""; dynamic y = x; float z = y;
ãããªããã°ã©ã ã¯ã³ã³ãã¤ã«ã§ããï¼ã¤ã¾ãéçãªåæ¤æ»ãéãï¼ããå®è¡ãã¦ã¿ãã¨z = y
ã§ã¨ã©ã¼ãèµ·ããããã®ãã¨ãããfloat
åã®å¤æ°z
ã«string
ã代å
¥ãã¦è¯ããã©ãããå®è¡æã«æ¤æ»ãã¦ãããã¨ãããããã¤ã¾ãz = y
ã®ã¨ããã§dynamic
ããfloat
ã®ãã£ã¹ããæ¿å
¥ããã¦ããã¨èãã¦ããã£ã¹ããå®è¡æã«æ¤æ»ãã¦ããã¨è§£éãããæ¤æ»ã«å¤±æãããRuntimeBinderException
ãçºçããã
ãã£ã¹ãã«æ³¨ç®ããã°ãJavaã®Object
ã¨ãããã®ã°ã«ã¼ãã«å
¥ãï¼ããã°ã©ãã«ããæ示çãªãã£ã¹ãã¯å¿
è¦ãªã®ã§ãdynamic
ã¨ã¯ããªãæ¸ãå³ãéããã©ãããã¯ããã¦ããã¨ãã¦ï¼ãã¤ã¾ãããã£ã¹ãã¯å¿
ãå®è¡æã«æ¤æ»ããã¦ã失æããã¨ãã«ãªã«ãèµ·ãããã¯è¨èªã«ãã£ã¦å®ç¾©ããã¦ããããããã¯ãC++ã®dynamic_cast
ãã失æãå¤å®ã§ãã¦å¤±æããã¨ãã®æåãå®ç¾©ããã¦ããã¨ãã観ç¹ã§ãã¡ãã«å
¥ãã
ãã¦ããã£ã¹ãã®å¤±æã§ãªã«ãèµ·ããã®ãã¯å®ç¾©ãããããã«ãªã£ãã®ã ãããæªå®ç¾©ã§ã¯ãªããã¤ã¾ãï¼å°ãªãã¨ããã®é¢ã«ããã¦ï¼C#ãJavaã¯ãå®å ¨ãã«ãªã£ãã
å®å ¨ãªãã ãã©æ¤æ»ãçç¥ããããã® - any (TypeScript)
dynamic
ã¾ã§ã ã¨è©±ã綺éºãªãã ãã©ãTSã¯ã¾ãå³ããã¨ãããã¤ãã¦ãã¦ãã¡ãã£ã¨é£ããã
TSã§ã¯any
ããä»ã®åã¸ã®ãã£ã¹ãã¯å®è¡æã«æ¤æ»ãããªãããããå®å
¨ãããªãã®ãã£ã¦ããã¨ãå®å
¨ã§ãããã¤ã¾ããJavaScriptã¨ãã¦å®è¡ãããã®ã§ããã£ã¹ãã®å¤±æãè¦éãããã¨ã«ãã£ã¦çºçããåé¡ã¯ãã©ã¡ãã«ãã¦ãJSã®ã©ã³ã¿ã¤ã ã«ãã£ã¦ä¿è·ããã¦ããã®ã ãã©ããå®å
¨ãªãã ããããã£ã¹ãã®éã®åæ¤æ»ãçç¥ãã¦ãè¯ãã¨ããçºæ³ãããã¯ãããªãå¼·çãªæ§è³ªã§ãJava以éã®ããã°ã©ãã³ã°è¨èªã«ããªãåºãå
±æããã¦ããããã£ã¹ãã®ãããªéçãªåæ¤æ»ã§ã¯åé¡ãæ¤æ»ã§ããªãæä½ã«ã¯ãå®è¡æã®ãã§ãã¯ã§è£å®ããããã¨ããæ¦ç¥ããé¢ãã¦ãããã¨ãæå³ããããããã
éã«è¨ãã¨ããã®ããã£ã¹ãã®æ¤æ»ãã諦ãããã¨ã«ãã£ã¦ãTypeScriptã§ã¯ããªãæè»ãªåãæ¸ããããã«ãªã£ã¦ãããä»®ã«ããã£ã¹ãã®æ¤æ»ãããæ¹åã§ãã¶ã¤ã³ããã¨ããã¨ãJSã®ã©ã³ã¿ã¤ã ã§è¡¨ç¾ã§ããåãã使ããªããã¨ã«ãªãã®ã§ããã£ããå³ãããæè¿ã¯ã¯ã©ã¹ãå
¥ã£ãã®ã§è¯ããã ãã©ãå°ãåã¾ã§ã¯object
ã¨number
ã¨string
ã¨array
ã¨â¦â¦ããããããªãã£ããããã®å¼ã®åã¯object
ã§ãï¼number
ã¨ãstring
ã§ã¯ãªããã©ãã©ãããã¡ã½ãããããã®ãã¯ãããã¾ããï¼ãã¨ããåä»ãã¯ããã¾ãå®ç¨çã§ã¯ãªããTSã§ã¯ããªãã¸ã§ã¯ãã®åãããªã詳細ã«æ¸ããããã«ãªã£ã¦ãã¦ãã¾ãç¾å®çã§ã¯ãªãæãã®ã©ã³ã¿ã¤ã åæ¤æ»ã«ãªããï¼ãã¡ããããã°ã§ããã ï¼
ããããããã§ãany
ããã®ãã£ã¹ãã§æ¤æ»ãçç¥ããã¨ããã®ã¯ã¾ãç¾å®çãªå¤æã ã¨æããã ãã©ãæå¤æ§ã¯ããã®ã ã£ãã
ã¡ãªã¿ã«ãany
ããªãã¦ãTSã®é
åã¯covariantãªã®ã§ããã®ç¹ã§åæ¤æ»ã¯å¥å
¨ã§ã¯ãªãã
const xs: string[] = [] const ys: (string | number)[] = xs // æ¬å½ã¯ãã®ä»£å ¥ãã§ãã¦ã¯ãããªã ys.push(1) const s: string = xs[0] // æ¬å½ã¯number
ï¼ã©ããä¸åany
ãä»ãã°ä»£å
¥ã§ãã¦ãã¾ããã ãããã¾ãæ°ã«ããã«covariantã«ããã®ãæ£ããã®ã ãããï¼
宣ä¼
ç¹ã«ããã§æ¸ããä¸ã§ã¯TypeScriptã«é¢ä¿ãæ·±ãã®ã§ããããåçåä»ãã®è¨èªã«åãä»ãããã¨ãã人é¡ã®è©¦ã¿ãã«ã¤ãã¦ä¸å話ãããããªã¼ã¨æã£ã¦ãã¦ããã£ãããªã®ã§å¯å±±Rubyä¼è°ã§ãããã¨ã«ãã¾ããã
ãããã人é¡ã試è¡é¯èª¤ããæ´å²ãç§ãç解ãã¦ããéãã§è§£èª¬ãã¦ãããããRuby (Steep) ã§ã©ãããã®ï¼ãã¨ãã話ããã¾ããã¿ãªãã¾ãµãã£ã¦ãåå ãã ããã
GrillRB 2019ã«ãã£ã¦ãã
ãã¡ãã§ãã
話ã¯å¤§ä½ãã¤ãã®ãã¤ã§ãããã¡ãã£ã¨åãä»ãã¦ããã°ã©ãã³ã°ãã¦ãããã¨ã«è¸ã¿è¾¼ãã å 容ã§ããã*1
ãã®GrillRBã¨ããã®ã¯ããã¼ã©ã³ãã®ã°ããã¯ãã¨ããé½å¸ã§éå¬ãããã«ã³ãã¡ã¬ã³ã¹ã§ã大ããªç¹å¾´ã¨ãã¦ãä¼å ´ãå±å¤ããæä¾ãããé£äºããã¼ããã¥ã¼ãã¨ãã2ç¹ãããã¾ãã
ãã¼ã¯ããã¦ããã¨ã ãã ãèãç¼ããåããæ¼ã£ã¦ããã¨ããã楽ããä½é¨ãã§ãã¾ãããå±å¤ã§è©±ããã¨ãããã¨ã§ã¹ã¯ãªã¼ã³ãããªãå³ããã®ã§ã¯ãªããã¨æ³åãã¾ãããããã³ãã®ä¸ã«ãã¬ããäºå°ãã£ã¦ã¾ãä½è£ã§ããã
å°ããè¡ã§ãããã«ãã¨ã¼ãããã¨ããè¦ãç®ã§ã楽ããã£ãã®ã§ãããã¾ã建ç©ãçºãã¦ããã¨ããã«é£½ãã¾ããç¾è¡é¤¨ã«è¡ã£ã¦ã¿ã¾ãããããæã®çµµã¯å¤§ä½ããªã¹ããããªã¢ããæ代ãå°ãä¸ããã¨åã人ã®ãã¼ãã¬ã¼ãã«ãªããã¨ãããã¨ãå¦ã³ã¾ããã
ä¸ã®åçã¯å°äººã§ããªãã好ãåæã«ãã®è¾ºã®å»ºç©ãä½ã人ãå¢ããã¦ãããããã§ããããã¯PCå±ããã®åãªã®ã§ãã¼ãã¼ããæã£ã¦ãã¾ãã
楽ããã®ã§ãæ¥å¹´ä»¥éãçãããåå ãããã¨è¯ãã¨æãã¾ããï¼ãªããã¹ãã¼ã«ã¼å«ãã¦å¤§ä½ã®åå è ã¯ãã¼ã©ã³ããã¨ã¼ãããããã§ããã¹ã§ãããã¿ãããªæãã§ããé£è¡æ©ã§14æéãããããã£ã¦ç§»åãã¦ããã ãã©â¦â¦ãã¨ããé£ããæ°æã¡ã«ãªãã¾ããï¼
*1:ãã¨ä¾ã«ãã£ã¦æ¥æ¬äººãããªãã£ãã®ã§ããã®è¾ºãæèããå°å ¥ã«ãªã£ã¦ããã
Sorbetã«ã¤ãã¦
æ¨æ¥ã®Asakusa.rbã«è¡ã£ããSorbetã«ã¤ãã¦èãããã®ã§ãå°ã話ãããã ãã©ãã¡ãã£ã¨ãã¡ãã¨ç¢ºèªããªãã¾ã¾è©±ããããã ãã ã ã£ãã®ã§ãããå°ãã¾ã¨ãã¦ããã
å ¨ä½çãªè©±ã¨ãã¦ãSorbetã¯ã¨ã¦ãè¯ãã§ãã¦ããã®ã§ãããã§è¯ãã¨æã人ã¯ããã§è¯ãã¨æãã¾ãã
$ srb --version Sorbet typechecker 0.4.4306 git 31ef906fe5eb572865f2b5d3ea5805793554c676 built on 2019-06-25 06:45:18 GMT with debug symbols
Rubyã¨å°ãåããªãã¨ããã¯ããã®ã§ããã®è¾ºãæããã
1. ãµãã¿ã¤ãã³ã°
ããããDuck typingã¨ãããã¤ããã¾ãè¯ããªãã
sig { params(arg: Eachable).void } def push_from(arg) arg.each do |x| @array << x end end
ã¿ãããªã®ããã®å¼æ°ã®Eachable
ãç¹å®ã®ã¯ã©ã¹ãªãè¯ããã ãã©ãeach
ãå®ç¾©ãããèªä½ã®ã¯ã©ã¹ã渡ãããArray
ã渡ãããããã¨ã¡ãã£ã¨é£ãããã¨ã«ãªãã
ãªããã ãã©ãworkaroundã¯ç¨æããã¦ããã®ã§ãããã§è¯ã人ã¯ããã§è¯ãã¨æãã
# .rbiã«æ¬²ããã¡ã½ãããå®ç¾©ãããã¢ã¸ã¥ã¼ã«ãå®ç¾©ãã module Eachable sig { params(blk: T.proc.params(x: String).void).void } def each; end end # .rbã«ã¢ã¸ã¥ã¼ã«ãå®ç¾©ããï¼ãã®ãã¡ã¤ã«ã¯åæ¤æ»ããªãï¼ # typed: false module Eachable # ããã¯includeã§ããã°ããã®ã§ç©ºã§è¯ã end # å¥ã«.rbã«ã¯ã©ã¹ãªã©ãå®ç¾©ãã class A # ãã®includeã«ãã£ã¦Aã®ã¤ã³ã¹ã¿ã³ã¹ã¯Eachableã«ãªã£ã include Eachable def each(&blk) yield "foo" yield "bar" yield "baz" end end push_from A.new # ãããokã«ãªã
åããã¦ãªããã ãã©ãããã§ãããã¯ãã
ãæ¢åã®ã¯ã©ã¹ã«ã¤ãã¦ãå¾ããinclude
ãããã¨ã§Eachable
ã«ã§ãããã¨ããã®ããã¤ã³ããªãã ãã©ãArray
ã§ãããã¨ãããåãé£ããã£ãã®ã§è«¦ããâ¦â¦
2. åã®æ§æ
好ã¿ã®åé¡ãªã®ã§ããããè¯ãã¨æã人ãä¸ã®ä¸ã«ã¯ããã®ãããããªãã
çµæ§å¼·çãªã®ã¯
def initialize(x:) @x = T.let(x, String) end
ã®ãããªãT.let
ã¡ã½ããã§ã¤ã³ã¹ã¿ã³ã¹å¤æ°ã®åãæ¸ããã ã¨æãã
3. Overloading
ã§ããªãã¿ãããSorbetã®.rbi
ã«ã¯è¤æ°ã®sig
ãä¸ã¤ã®def
ã«å¯¾ãã¦ä»ãããã¨ãã§ããªãã¿ããã ã
Array#map
ã¨ãã¯ã©ããªã£ã¦ããã®ãã¨ããã¨ãæ¨æºã©ã¤ãã©ãªã¯ç¹å¥æ±ãã«ãªã£ã¦ããããã«ã¿è¦ããã # typed: __STDLIB_INTERNAL
ãªã©ã¨æ¸ãã¦ããã
ã§ãããã ã¨å°ããããªæ°ãããã®ã¯
def fetch_people if block_given? yield people.get(id) else people.get(id) end end
ã¿ãããªããããã¯ããã£ããyield
ãã¦è¿ãå¤ãè¿ãããã¿ã¼ã³ã§ãããåã¯çµæ§æ¸ãã®ã§ãã¡ãã£ã¨è¦ããã¨æãã
4. Runtime
ã©ã¤ãã©ãªã«ä½¿ããã¨ããã¨ãRubyã³ã¼ãã®å®è¡ã«è¨èªå DSLã®ããã®ã©ã³ã¿ã¤ã ãå¿ è¦ãªã®ã§ãã¾ãããã©ããªã®ã¨ããã
ã©ã³ã¿ã¤ã ããããã¨ã®å©ç¹ã¯ãã£ã¦ãã©ã³ã¿ã¤ã ã®åæ¤æ»ãã§ããããã«ãªãããTyped Structsã¿ãããªä¾¿å©ã©ã¤ãã©ãªãããã®ã§ããªããªãé£ããã¨ããã ã¨æãã
ææ³
åã¯ã
- 絶対ã«Runtimeã®æåãå¤ããããªãããgemã«ã¯Runtimeã®ä¾åé¢ä¿ãå¢ãããããªã
- åã®æ§æãè¦ããï¼ä½æ¥ãããã°æ £ãããããããªããã©ï¼
- Overloadingãå ¨ç¶æ¸ããªãã®ã¯ãããã«åé¡ã§ã¯
- å®ã¯Structural subtypingã«ãã ããã¤ããã¯ãªããã ãã©ãä»ã®workaroundã«å¿ è¦ãªæ§æã¯ãããã«è¦ããã¨æãã
ãããã®æè¦ãããã¾ãã
JSONãYAMLã®ãã¼ã¿æ§é ããã§ãã¯ããã©ã¤ãã©ãªStrongJSONã®ãç´¹ä»
JSONãYAMLã使ãã¨ãããªãè¤éãªãã¼ã¿ãä½æã§ãã¾ããããããæå³éãã®å½¢å¼ã«ãªã£ã¦ãããã確èªããã®ã¯èªæã§ã¯ããã¾ãããXMLã«ã¯XML Schemaãããã¾ããããããªæãã®ãã®ãJSONã«ã欲ããã£ãã®ã§ãä½ãã¾ããã
ãããªæãã§ä½¿ãã¾ãã
Schema = StrongJSON.new do let :phone, object(phone: string) let :email, object(email: string) let :contact, enum(phone, email) let :person, object(name: string, contacts: array(contact)) end json = Schema.person.coerce(JSON.parse(input, symbolize_names: true)) # symbolize_namesãå¿ è¦ã§ã
ææ°ãã¼ã¸ã§ã³ã¯1.1ã¨ãã§ãæè¿ã人éã«ãèªããã¨ã©ã¼ã¡ãã»ã¼ã¸ããå®ç¾ãã¾ããã®ã§ãã¿ãªãã¾ãæ´»ç¨ãã ãããä¾ãã°ãã¹ãã«ããä¾ãªãã§ããã
TypeError at $.items[0].price: expected=numeric, value=[] "price" expected to be numeric 0 expected to be item "items" expected to be items $ expected to be checkout Where: item = { "name": string, "count": numeric, "price": numeric } items = array(item) checkout = { "items": items, "change": optional(number), "type": enum(1, symbol), "customer": optional( { "name": string, "id": string, "birthday": string, "gender": enum("man", "woman", "other"), "phone": string } ) }
ã¨ãåºããã®ã§ãå°ãé å¼µãã°äººéã«ãèªããããããªãããªãããã®ã¾ã¾ã¢ããªã±ã¼ã·ã§ã³ã«çµã¿è¾¼ãã§ä½¿ã£ã¦ããä¾ã¨ãã¦ã¯ã sider/goodcheckãããã¾ãããã®ã¾ã¾ã¢ããªã±ã¼ã·ã§ã³ã«çµã¿è¾¼ãã°è¯ãã¨ãããã¨ã§ãYAMLãã¡ã¤ã«ã¨ãã§è¨å®ãæ¸ãããã¨ãã«ãvalidationã§ãã¦ä¾¿å©ã§ã¯ãªããã¨æãã¾ãã
JSON Schema
ãã¦ãã¨ããã§ä¸ã®ä¸ã«ã¯JSON Schemaã¨ãããã®ããããã¨ããåãã®äººãããã§ããããJSON Schemaã§ã¯ãã¡ãªã®ãã¨ããã¨ãã¾ãå¥ã«è¯ããã§ããã©ã
- SchemaãJSONã«ãªã£ã¦ãã¦æ¬²ããæ°æã¡ãå¥ã«ãªã â Ruby DSLã§Schemaãæ¸ãããã«ãã
- ãæ°åãã¨ããæååãã¨ãããããæãããã¹ããããã®ã§ãã£ã¦ããé»è©±çªå·ãã¿ãããªãã¼ã¿åã¯ãããªã
ã¨ããæãã§ãã
YAMLã§ã¯
Rubyã®YAMLã©ã¤ãã©ãªã ã¨ãã¾ã大ä½JSONã¿ãããªãã¼ã¿æ§é ã«ãªããã®ã§ãããã§ããã¾ããJSON以å¤ã®ãã¼ã¿æ§é ãã§ããã¨æãã¾ãããããããã®ã¯ãã¡ã§ãã
ã©ãããååãªãããï¼ï¼
Railsã®Strong parametersããã®åç¨ã§ããStrong parametersã¯ãã¯ã¨ãªãã©ã¡ã¼ã¿ã¿ãããªæ§é ã¯ä¸æãå¦çã§ããã®ã§ãããJSONã¿ãããªã®ãæ±ããã¨ããã¨å¹¸ããªæãã§ã¯ãªãã®ã§ä½ãã¾ããã
ããå®ã¯ãã®ã©ã¤ãã©ãªã¯5å¹´ãããåããä½ã£ã¦ãã¦ãå½æã®Strong parametersã¨ä»ã®strong parametersã®éãã¨ãã¯ç¥ããªãã®ã§ãããããããRailsã®ã§è¯ãã®ããããã¾ããã
åã¯ã¤ãã®ï¼
ã¤ãã¾ããJSONã¯ãã¾ãè²ã
ããã㧠any
ã«ãã¡ããã®ãè¯ãã¨æãã¾ãããããã¤ããã¬ã³ã¼ãåã®ãã¼ã¿ãä¾ãã° { name: String, contacts: Array[contact] }
ã«å¤æããã¨æã£ã¦ãã ãããå¤æã§ããªããã®ã¯ã¨ã©ã¼ã«ãªãã
ä¸æ¹ã§ããã®åä»ããä¸çªä¾¿å©ãã¨ããã¨ãããªãã¨ã¯ãªãã¦ãé å¼µãã°åãã¤ãã¨å¼·å¼ã§ããããããã®ç¨åº¦ã§ãã¾ãSteepãç´ããªãã¨ãããªãã§ãããâ¦â¦
Balkan Rubyã«è¡ã£ã¦ãã
- å»å¹´ https://2018.balkanruby.com
- ä»å¹´ã®ãå¹´çªå·ãã¤ãã¨äºæ³ https://2019.balkanruby.com ï¼ã¾ã ãªããã©ï¼
Genadiãèªã£ã¦ãããã®ã§ãBalkan Rubyã«è¡ã£ã¦ããã®ã ã£ãã話ã¯ãã¤ãã®ãã¤ã
RubyKaigiã§Matzã¨ã id:ku-ma-me ã¨ãã話ãã¦ããã ãã©ã大ä½ãããªæãã«ãªã£ã¦ããã¯ãã§ããç§ã®è¨èã«ãªã£ã¦ãããã©ãå 容çã«ã¯æ°ãããã¨ã¯ããã¾ããã
ãã¼ã¯ã®è©±ã¯ãã®ãããã«ãã¦ãBalkan Rubyãè¯ãã£ã話ããããã¨æãã
ãªã¼ã¬ãã¤ã¶ãæåã
ããã«ãåã£ã¦ããããã空港ããããã«ãæé ãã¦ããã¦ããããããã«ã«ã¤ãããSIMãããããã飯ããããã§ãç¹ã«ãªã«ãèããã«ãã¼ã¯ã®å 容ã ãæºåãã¦Sofiaã«è¡ãã°è¯ãã®ã§æ¥½ã ã£ã*1ã2æ¥åã®åå¾ã«Sofiaã«ã¤ãããã ãã©ããã®ã¾ã¾æ¢ã«Sofiaå ¥ããã¦ããã¹ãã¼ã«ã¨æ©ã飯ã«ãªã£ã¦ããããã®æµãã§ãã ãããæ¯é£ã¹ãã¼ã«å士ã§ã飯ãé£ã¹ã¦ããã
ããã¯Rakiaã¨ããé ã§ãã«ã¬ãªã¢äººã¯ããã飲ã¾ãã¦ãããå¼·ãï¼40ã50%ï¼ã®ã§æ³¨æãããã¨ã
ãªãã§ãããªã«ã¹ãã¼ã«ã®ä¸è©±ãæåããã ãã¨èãã¦ã¿ãããã¹ãã¼ã«ã®æ°ãå°ãªãããããªã©ã¨è¨ãããã®ã§ãã¾ã確ãã«ããã¨ããæãã
Sofiaã楽ãã
ããªã«æåã¨ã建ç©ã¨ãã«ãã·ã¢ã¨ãã½ãã¨ãã¿ãããªæãããã£ã¦ãã¨ã¼ãããã¨ãéã£ã¦æ¥½ãããã¨è¨ãã¤ã¤ãç§ã«ã¨ã£ã¦åã®ã¨ã¼ãããã®å½ã ã£ãã®ã§ä»ã®ã¨ã¼ãããå°åã®ãã¨ã¯è¯ããããããçºä¸¦ã¿ã¯ç¶ºéºã§ãæ´ãã¦ããã¨é ãã«å±±ãè¦ãã¦å¤§å¤ã«æ¥½ãããå ¬åã«ã¯äººã ããã¦ãå°ããåã©ãã¨ããéãã§ããããã®ã§ãå¹³åã§è¯ãæ°æã¡ã«ãªãããç¹ã«å¤é ãã¾ã§æããã®ã§ï¼ç·¯åº¦ã®ãããçµåº¦ã®ãããã¯ããããªãï¼ãã«ã³ãã¡ã¬ã³ã¹ãçµãã£ã¦å¤ã«åºãã¨ãã«ãã¾ã 4æãããããªï¼ï¼ãã¨æã£ããå®ã¯7æéãã ã£ããããã®ã§å±ãªãã
Balkan Rubyã®åå è ã¯å¤§ä½ãã«ã¬ãªã¢äººãªãã ãã©ãã¹ãã¼ã«ã¯ã¨ã¼ãããåå½ããã§ãããã«å ãã¦ã¢ã¡ãªã«ã»ã¢ã¸ã¢ãæ°äººã¨ããé¡ã¶ãã ã£ãããããªã«ã¨ã¼ããã人ãå¨ãã«ãããã¨ã¯ããã¾ããªãã£ãã®ã§ãã¡ãã£ã¨ä¸æè°ãªæãã ã£ãã
Balkan Rubyãçµãã£ãæ¥ææ¥ã¯è±èªã§ç¡æã®å¸å ãã¢ã¼ï¼2æéï¼ããã£ã¦ãããããã®ã«è¡ã£ã¦ã人ãããã
ã©ã¼ã¡ã³å±ããã£ãã®ã§ãã£ããå ¥ã£ã¦ãã¾ã£ãããä¼è¨ã®ã¿ã¤ãã³ã°ã§ã«ã¼ãæ¯æããã§ããªããã¨ãçºè¦ããATMã¾ã§ç¾éãä¸ããã«èµ°ã£ãããã以å¤ã¯å ¨é¨ã«ã¼ãæ¯æãã§ããããããæ²¹æãã¦ããã
Siderã§ä½¿ã£ã¦ããTSLintã®è¨å®
ä»ã®ã¨ãããããªãã§ãã
{ "extends": [ "tslint:latest", "tslint-immutable" ], "rules": { "array-type": false, "arrow-parens": false, "interface-name": false, "interface-over-type-literal": false, "max-classes-per-file": false, "max-line-length": false, "member-access": false, "object-literal-key-quotes": [true, "as-needed"], "object-literal-shorthand": false, "object-literal-sort-keys": false, "ordered-imports": false, "quotemark": false, "semicolon": false, "trailing-comma": false, "variable-name": [ true, "ban-keywords", "check-format", "allow-leading-underscore", "allow-pascal-case" ], "whitespace": false, "no-angle-bracket-type-assertion": false, "no-shadowed-variable": false, "no-namespace": false, "readonly-keyword": [true, "ignore-class"], "no-trailing-whitespace": false, "no-implicit-dependencies": [true, ["i18n-js"]], "no-submodule-imports": false } }
ç¹ã«è§£èª¬ã¯ãªãã®ã§ããã
- ã¹ã¿ã¤ã«é¢é£ã¯åºæ¬çã«ç¡å¹
- ãªããæããã度ã«ç¡å¹ã«ãã¦ãã
==
ã£ã¦æ¸ãã¨æããã¤ã¯æ¬²ãã
ã¿ãããªéãªè¨å®ã§ãã£ã¦ãã¾ãã
ä¸ã¤ã ãæå¹ã«ãã¦ãããã©ã°ã¤ã³ããã£ã¦ãtslint-immutableã§ããããã¯æã
ãreduxã使ã£ã¦ããããã§ãstateã®ããã®interfaceã®attributeãimmutableã«ããã®ãå¿ããªãããã«ãã¦ãã¾ãããã®ãã©ã°ã¤ã³ã¯ãªããªã便å©ãªã®ã§ãããä¸ã¤åé¡ããã£ã¦ããã種ã®åé©ç¨ã« immutable
ã¨æ¸ããããªãã¨ãã話ãããã¾ãã
ãããªãã
const routes = { assignSeat: new ApiRoute<{orgId: number, memberId: number}>( "/api/c/gh/orgs/:orgId/members/:memberId/seat_assignments" ) } const url = routes.assignSeat.stringify({ orgId: 123, memberId: 456 })
ãã®ApiRoute
ã¨ããã®ã¯ãAPIãªã¯ã¨ã¹ãã¨ãã§ä½¿ãURLçæã®ããã®ã¯ã©ã¹ã§ã orgId
ã«æååã渡ããã null
ãå
¥ã£ãããããã¨ãé²ããåªããã®ã§ãããããã§ãã¡ãã¡ readonly
ã¨æ¸ããããªãã¨ããåé¡ãããã¾ããè¯ãæãã®ãªãã·ã§ã³ããªãããã©ããªã¨ãã« readonly
ã¨æ¸ããªãã¦è¯ãããã°ããèãããã©å¤å®æ¹æ³ãæãã¤ããªãã®ã§ããã諦ãã¦ãã¾ã£ã¦èª¤çãåºãã¨ç¡è¦ããããã«ãã¦ãã¾ããï¼Siderã使ãã¾ããï¼