TypeScriptã¯åå®å ¨ãããªããããã°ããã
ãTypeScriptã§ã¯ãããåã·ã¹ãã ãã¨ããè¨äºãnæåã©ã ããã¼ãã«å¯ç¨¿ãã¾ããã
æ°åãçºå£²ãã¾ãã "ãnæåã©ã ããã¼ããVol.4 No.3ï¼2024ï¼çºè¡ã®ãç¥ãã https://t.co/PGppk1aRRA
— lambdanote (@lambdanote) 2024å¹´10æ4æ¥
ã©ããªå 容ï¼
TypeScriptã®æ¥µå°ãµãã»ããã«å¯¾ããåæ¤æ»å¨ãæ¸ãããããéãã¦åã·ã¹ãã ãä½æãã¦ã¿ãããã¨ããå 容ã§ãã
詳ããè¨ãã¨ãbooleanåã¨numberåã¨é¢æ°åãããªãTypeScriptãµãã»ããè¨èªãã¿ã¼ã²ããã§ãã åæ¤æ»å¨ã®å®è£ è¨èªã«ãTypeScriptï¼å¦çç³»ã¯Denoï¼ã使ãã¾ãã TypeScriptã¥ããã®ä¸åã§ãã
ããã人åãã«è¨ãã¨ããåã·ã¹ãã å ¥éãã¨ããæ¬ï¼é称TAPLï¼ã®åç´åä»ãã©ã ãè¨ç®ã«ç¸å½ããå 容ãTypeScriptã§èª¬æãã¦ã¿ãããã ãå®çã証æã¯ãã¹ã¦çãããã¨ããæãã§ãã
ãªãæ¸ããï¼
ãã£ãããããã¤ãããã¾ããã
TypeScriptçéã§TAPLãèªã¾ãã¦ãããããã¨èãã
ãã¨ãã¨ãåã·ã¹ãã ãå®åããã°ã©ãåãã«èª¬æããè¨äºãæ¸ãã¦ã¿ããã¨ããæ°æã¡ã¯ãã£ã¨ããã¾ããã TAPLã¯æ å ±ç§å¦å°æ»ã®å¤§å¦é¢çåãã®æç§æ¸ãªã®ã§ãããåã·ã¹ãã ã¨ãããã£ããã¼ãªå 容ãããå®åããã°ã©ãã«ã注ç®ããã¦ãã¾ãã ãããTAPLã¯ããã¾ãå®åã§è¦ãããªãMLã¨ããè¨èªã§èª¬æããã¦ããä¸ãå®çã¨è¨¼æãç´é¢ã®ååããããå ãã¦ããã®ã§ããéä¸ã§è±è½ããããåã·ã¹ãã å ¥éå ¥éã欲ãããã¨ãã話ãããèãã¦ãã¾ããã
TAPLã翻訳ããã®ã¯12å¹´ãåã®ãã¨ã§ãããä»å¹´ã«ãªã£ã¦æ¥ã«ãæ¥æ¬ã®TypeScriptçéã§TAPLãèªãã§ãã人ãã¡ãçµæ§ãããããã¨å°è³ã«ã¯ãã¿ã¾ããã ãããè¤æ°ã®çµè·¯ã§åæå¤çºçã«ã ãã®ãã¡ã®ã²ã¨ã¤ã§ã¯ãTAPLã®è¨³è ã¨ãã¦å£°ãããã¦ããã ãããã¼ã¯ããã¦ãããã¾ããã
ãåã·ã¹ãã å ¥éãã®ã¤ãã³ãããã«ã¯ãã¬ã¯ãTAPLã«ã¿ãã¨ããã«åå ãã¾ãããã©ã®çºè¡¨ãããããããããããã人ãã¡ã¨è©±ãã¦ã¨ã¦ã楽ããä¼ã§ããã
— Yusuke Endoh (@mametter) 2024å¹´7æ24æ¥
èªåã¯TAPL翻訳æã®ã¨ãã½ã¼ãã話ããã®ã§ãè³æãããã¦ããã¾ã #TAPLts https://t.co/Ohvzwn95uF
ããã§ãããã¾ããè¨äºãæ¸ãã¹ããªã®ã§ã¯ï¼ãã¨ããæ°åãé«ã¾ãã¾ããã
TypeScriptã®è£å´ã調ã¹ã¦ã¿ããã£ã
ããã²ã¨ã¤ã®åæ©ã¨ãã¦ã¯ãTypeScriptã®è¨è¨æ¹éãåæ¤æ»å¨ã®å®è£ ãå°ãçé¢ç®ã«ç解ãã¦ã¿ããã¨æã£ããã¨ã§ãã ç§ã¯TypeProfã¨ããRubyã®å解æå¨ãéçºãã¦ã¾ãã
TypeProfãä½ãããã§ãTypeScriptã¯ããããåèã«ãã¦ã¾ãã ãã ãTypeScriptã®ã¦ã¼ã¶ã¨ãã¦ã®ä½é¨ã¯å¤å°ç¥ã£ã¦ããã¤ããã§ãããè£å´ãçé¢ç®ã«è¦ããã¨ã¯ãªãã£ãã®ã§ããããã§å°ãã ããã¡ãã¨èª¿ã¹ã¦ããããã¨æã£ã¦ããã®ã§ããã ãã®å·çã¯ããã®ãã£ããã«ããªãã¾ããã
TypeScriptã¯åå®å ¨ãããªãï¼
ãããã¦èª¿ã¹ã¦ãããã¡ã«ããã£ãã®ã§ãããTypeScriptã¯ã¨ã¦ãããæå³ã§ãéãã«ä½ããã¦ããã¨ãããã¨ããããã¾ããã ããã¯ã漸é²çåä»ããã©ãããã¨ãã話ã§ã¯ãªãããã£ã¨å ¨ä½çãªè¨è¨ã»å®è£ æ¹éã®è©±ã§ãã
TypeScriptãè¦éãã¨ã©ã¼
å ¸åçãªä¾ã¨ãã¦ã¯ã次ã®ãããªæªåæåå¤æ°ã®åç §ãããããã°ã©ã ãåã¨ã©ã¼ã«ãªãã¾ããã
TypeScriptã®åãã§ãã¯ã¯ãã¹ãããã ãã©ãå®è¡ããã¨ã¨ã©ã¼ã«ãªãã³ã¼ããè¦ã¤ãããæã£ã¦ããããªãã·ã§ã³ã¨ãããã®ããª
— Yusuke Endoh (@mametter) 2024å¹´6æ15æ¥
const f = () => x;
f(); //=> Cannot access 'x' before initialization
const x = 1;https://t.co/axWeEStF0c
åæ¤æ»å¨ããã®ãããªè¦éããããå ´åãåå®å ¨æ§ãããã¨ã¯è¨ããªãã®ããµã¤ãã ã¨æãã¾ãã ããã¯TDZï¼Temporal Dead Zoneï¼ã¨å¼ã°ããJavaScriptã®ä»æ§ãªã®ã§ãã¡ãã£ã¨èãã¦ã¿ãã¨ãJavaScriptã®æ§æãä¿ã£ãã¾ã¾è§£æ±ºããã®ã¯ããããããã§ãã å®éãTypeScriptã«issueãããã£ã¦ãã¾ãããããã£ãã«åºã¦ããªãã±ã¼ã¹ãªã®ã§æ°ã«ãããªãã¨ãããã¨ã§Wontfixã¨ãªã£ã¦ã¾ããã
ä»ã«ãããå ¨ç¶é¢ä¿ãªãå¤æ°å®£è¨ãåé¤ããã¨ãåºãã¹ãã¨ã©ã¼ãæ¶ãã¦ãã¾ããã¨ãããããªãç解ä¸è½ãªæåãããä¾ãä½ãã¦ãã¾ãã¾ããã
TypeScriptã®ãã®ä¸æè°ãªæåã説æã§ãã人ãã¾ãï¼https://t.co/QUOwpgu0uS pic.twitter.com/KweUd2WzEl
— Yusuke Endoh (@mametter) 2024å¹´7æ8æ¥
ã¡ãªã¿ã«ãTypeScriptãæ¬å½ã«åå®å ¨ã§ãªããã¯ãåå®å ¨ã®å®ç¾©ã«ããã¾ããJavaScriptã«ãã©ã³ã¹ãã¤ã«ãããã®ã§ãæªå®ç¾©åä½ã«é¥ããã¨ã¯åççã«ãªãããããTypeScriptã¯ä½ãããªãã¦ãåå®å ¨ã ãã¨ãã主張ããµã¤ãã«ãããã¾ãããã®ã¸ãã¯è¨äºã®ã³ã©ã ã«ããããæ¸ããã®ã§åç §ãã ããã
ããã§ãTypeScriptã¯ãããã®
ãéããåå®å ¨ãããªããã¨ããã¨ãTypeScriptãæªãè¨ã£ã¦ããã¨æãããããç¥ãã¾ããããã¾ã£ããéã§ãã
ç¾å®åé¡ã¨ãã¦ãTypeScriptã便å©ã§ãããã¨ã«ç°è«ãæã人ã¯å°ãªãã¨æãã¾ãã JavaScriptã¯æ§ããã«è¨ã£ã¦ãï¼åçåä»ãäºã 以åã«ï¼ããããã¨å³ããè¨èªã ã¨æãã®ã§ãããTypeScriptã¯JavaScriptã®ãã³ããè² ã£ã¦ãªã便å©ãªã®ã§ãæå¥ãªããããã§ãã
åã·ã¹ãã ã«è©³ãã人ã¯åå®å ¨æ§ãæ°ã«ããã¡ãªã®ã§ãããTypeScriptã¯ãå¥ã«å ¨é¨ã®åã¨ã©ã¼ãæ¤åºã§ããªãã¦ãããï¼åå®å ¨ãããªãã¦ããï¼ãã¨ããæãåã£ãå²ãåãããã¦ãã¾ãã ããã§ãã¦ããç¾å®çã«ãããããã°ã¯å¤§ä½æ¤åºã§ãã¦ä¾¿å©ãã¨ãã絶å¦ãªãã©ã³ã¹ãéæãã¦ãã¾ãã
ã¡ãªã¿ã«ãã¡ããã©kmizuãããã»ã¼åããããªãã¨ãè¨ã£ã¦ã¾ããã
åã·ã¹ãã ã®å°é家ã¯ï¼å½ç¶ãªããï¼soundnessãã£ã¡ãæ°ã«ãããæ°ããã¾ãããå®ç¨çãªè¦ç¹ããèããã¨ãå²ã¨ã©ãã§ãããunsoundãªã¨ããã¨ã©ãã§ããããªãunsoundãªã¨ãããããå°è±¡ãâ¦
— kmizu (@kmizu) 2024å¹´10æ2æ¥
TypeScriptã®è¨è¨è ã®è¨è
Anders Hejlsbergèªèº«ãã次ã®ããã«è¨ã£ã¦ãã¾ãã
If you can't achieve perfection then you don't even try to go there and that means you cut out a whole bunch of possible things that you could do that you might not be able to prove soundness for, but we don't have that restriction and that actually makes our work very interesting because we can go in places where people typically don't go.
éãªæ訳ï¼åã®ç 究è ã¯åå®å ¨æ§ã証æã§ãããã«ãªããã¨ã¨è©¦ããã¨ãããªãã®ã§ãå®ã¯ããããã§ãããã¨ãåãæ¨ã¦ã¦ãã¾ã£ã¦ãããTypeScriptã«ã¯ããããå¶ç´ããªãããã®ãããã§ããããã¯ãä»ã®åç 究è ããµã¤ãã¯è¡ããªãé åã«è¸ã¿è¾¼ããã®ã§ãã¨ã¦ãé¢ç½ãä»äºãã§ãã¦ããã
ãããåã®ç 究è ã«ã¯çµæ§è¾è¾£ã§ããã
å人çã«ã¯ããããããåå®å ¨ãããªãã¦ã便å©ãªå解æå¨ãã¯å®éã«åå¨ã§ãããã ã¨ããã®ã確信ã§ãã¦ããã£ãã§ãã TypeProfãããããã¨ãããç®æãã¦ãã¦ãå®ç¾ã§ããã®ãèªåã§ãåä¿¡åçã§ãã£ã¦ããã®ã§ãããéæããå®ä¾ãããã¨ããã®ã¯å¿å¼·ãæãã¾ããã TypeProfããã®ã¯ãªãªãã£ã¨ãã©ã³ã¹ãç®æããããã®ã§ãã
è¨äºã«ã¤ãã¦éå¤ãªãã¨
ãã¼ãµã¯ã©ããã
TypeScriptãµãã»ããã®åæ¤æ»å¨ãä½ãããã«ã¯ãã¼ãµãå¿ è¦ã ã£ãã®ã§ããããã®æ¸ãæ¹ã解説ãã¦ããã¨æ¥ãæ®ããã®ã§ããããããç¨æãã¦ããã¾ããã
https://github.com/LambdaNote/support-ts-tapl/blob/main/utils.ts
eslintã§ä½¿ããã¦ããtypescript-estreeãã©ããããæãã§ä½ã£ã¦ã¾ãã
TypeScriptããã¸ã§ã¯ãã®ããæ¸ãæ¹ãããããªãã£ãã®ã§ãã¨ããããDenoå°ç¨ã«ãªã£ã¦ã¾ãã TypeScriptã«è©³ãã人ãã¿ããå¤ãªæãã«ãªã£ã¦ãããªã®ã§ãé©å½ã«PRãããã¨ããããã§ãã
Rubyãããªãã®ã¯ãªã
Rubyã®åã®éçºã«åå ãã¦ããç«å ´ã§ãããªãããRuby + RBSãè¨äºã®é¡æã«ããªãã£ãã®ã¯ãä¸ã«æ¸ããåæ©ã®ã¨ãããªã®ã§ãããããã«æè¡çãªçç±ã¨ãã¦ãRubyã§ã¯ç¡åé¢æ°ã第ä¸ç´ã®è¨èªæ©è½ãããªãããã§ãã TAPLãã¼ã¹ã®åã·ã¹ãã ã説æãããã¨ããè¨äºã®æ¹åæ§ã«ã¯ãç¡åé¢æ°ãå¿ è¦ã§ããã ãã¡ããProcã¯ããã¾ãããdefã使ããã«Procã ãã§ããã°ã©ã ãæ¸ãã®ã¯ãµã¤ãã®Rubyãããªããããã®ã§ã
ç¶ããèªã¿ãã
åç´åä»ãã©ã ãè¨ç®ã§çµãã£ã¦ããã®ã§ã人ã«ãã£ã¦ã¯ãããã§çµããï¼ãã£ã¦æãããããã¾ããã basic.tsã¯é¨ååä»ããåã¨ã¤ãªã¢ã¹ãã¸ã§ããªã¯ã¹ãªã©ãä»ã足ãã¦ããããã®åå°ã«ãªã£ã¦ãã¾ãã ä»åã®åé¿ããããã°ããããã§è¨èªæ¡å¼µããã¨ããç¶ããåºãããã¨æã£ã¦ãã¾ãã
Rubyã§Slackã®ããããæ¸ãæ¹æ³ï¼ãªãã¹ãèªåã§ï¼
Rubyã§Slackã®ããããæ¸ãã«ã¯ãslack-ruby-client gemãruboty gemãªã©ã使ãã®ãä¸è¬çã ã¨æãã¾ãã ãããå人çã«ã¯ãSlackãããç¨åº¦ã§gemã使ãã®ã¯å¥½ã¿ã§ãªãã®ã§ããªãã¹ãç´ ã®Rubyã ãã§æ¸ãããã«ãã¦ãã¾ãã ãã®æ¹æ³ãã¾ã¨ãã¦ããã¾ãã
Slack appãç»é²ãã
ã¾ããhttps://api.slack.com/appsã§"Create New App"ãã¦ãé©å½ã«è¨å®ããã¾ãã
次ã®YAMLã"App Manifest"ã«è²¼ã£ã¦Save Changesããã¨ä¸æ°ã«è¨å®ã§ãã¾ãã
display_information: name: Sample Slack App features: bot_user: display_name: Sample Slack App always_online: true oauth_config: scopes: bot: - app_mentions:read - chat:write settings: event_subscriptions: request_url: https://example.com/ bot_events: - app_mention org_deploy_enabled: false socket_mode_enabled: false token_rotation_enabled: false
ããããã«èª¬æããã¨ãã¡ã³ã·ã§ã³ãããã¨ãã«éç¥ãåãåãï¼app_mentions:read Scopeã¨app_mention Event Subscriptionï¼ããã£ã³ãã«ã§çºè¨ããï¼chat:write Scopeï¼ãã¨ããè¨å®ã§ãã
ãªããã¡ã³ã·ã§ã³ã§ã¯ãªãçºè¨ãå ¨é¨åãåãããã£ããchannels:history Scopeã¨message.channels Event Subscriptionã足ãã¨ããã§ãã
ãããããSlackã«ã¡ãã»ã¼ã¸ãéã
chat.postMessage APIãå©ãã ãã§ãã æ¨æºã©ã¤ãã©ãªã ãã§ç°¡åã«ã§ãã¾ãã
require "net/http" require "json" TOKEN = "xoxb-..." # Bot User OAuth Token ãåãã CHANNEL = "CXXXXXXXX" # Channel ID ãåãã resp = Net::HTTP.post_form( URI.parse("https://slack.com/api/chat.postMessage"), { token: TOKEN, channel: CHANNEL, text: "Hello", } ) json = JSON.parse(resp.body, symbolize_names: true) pp json[:ok] #=> true on success, false on failure
å¿ è¦ãªè¨å®ã¯2ã¤ã§ãã
- Slack appã®è¨å®ç»é¢ã®"OAuth & Permissions"ããBot User OAuth Tokenãã³ãã¼ãã¦ã
TOKEN
ã«å ¥ãã - çºè¨ãããSlackãã£ã³ãã«ã®"View channel details"ã®æä¸é¨ã«ããChannel IDãã³ãã¼ãã¦ã
CHANNEL
ã«ããã
ãããã¦ã³ã¼ããå®è¡ããã°ãçºè¨ã§ããã¯ãã§ãã
ããã§ã¯åç´ã«"Hello"ã¨ããããã¹ããéã£ã¦ãã¾ãããtext: "Hello"
ã®ä»£ããã«æ¬¡ã®ãããªãã®ãæ¸ãã°ãSlackã®markdown風ã®ãã¼ã¯ã¢ãããã§ãã¾ãã
{ blocks: [ { type: "section", text: { type: "mrkdwn", text: "*Hello* `world`" } } ] }
ãã®ãããã«ã¤ãã¦è©³ããã¯Reference: blocksããåç §ãã ããã Block Kit Builderã§ã¤ã³ã¿ã©ã¯ãã£ãã«æ§ç¯ãããã¨ãã§ããããã§ãã
Slackããã¤ãã³ãéç¥ãåãåã
Slackãããã¡ã³ã·ã§ã³ãããããã誰ããçºè¨ããããªã©ã®ã¤ãã³ãã®éç¥ãåãåãã«ã¯ãEvents APIã使ãã¾ãã
2024å¹´ç¾å¨ãEvents APIã«ã¯2種é¡ã®éä¿¡æ¹æ³ãããã¾ãã
- publicãªHTTPãµã¼ããç«ã¦ã¦ãHTTPãªã¯ã¨ã¹ãã¨ãã¦éç¥ãåãåã
- WebSocketã§Slackã«æ¥ç¶ããããã·ã¥éç¥ãåãåãï¼Socket Modeï¼
両æ¹ããããã«èª¬æãã¾ãã
HTTPãµã¼ããç«ã¦ãæ¹æ³
sinatra gemã§HTTPãµã¼ããæ¸ãã¾ããgemã§ãããsinatraã¯èªåã®å¿ã®è¨±å®¹ãªã¹ãã«å ¥ã£ã¦ããã®ã§OKã¨ãã¦ãã¾ãã
require "sinatra" require "json" require "openssl" SIGNING_SECRET = "..." # Signing Secret ã§åãã def verify_signature(timestamp, body, sig_actual) msg = ["v0", timestamp, body].join(":") sig_expected = "v0=" + OpenSSL::HMAC::hexdigest(OpenSSL::Digest::SHA256.new, SIGNING_SECRET, msg) OpenSSL.secure_compare(sig_actual, sig_expected) end post "/" do body = request.body.read # Slack ããã® POST ã§ãããã¨ãæ¤è¨¼ãã halt 401, "{}" unless verify_signature( request.env["HTTP_X_SLACK_REQUEST_TIMESTAMP"], body, request.env["HTTP_X_SLACK_SIGNATURE"] ) json = JSON.parse(body, symbolize_names: true) case json[:type] when "url_verification" # Slack ã« URL ãç»é²ããã¨ãã®ã¤ãã³ããchallenge ããã®ã¾ã¾è¿ãã°è¯ã json[:challenge] when "event_callback" event = json[:event] case event[:type] when "app_mention" # ã¡ã³ã·ã§ã³ããã p event[:text] end "" else "" end end
å¿ è¦ãªè¨å®ã¯1ã¤ã ãã§ãã
- Slack appã®è¨å®ç»é¢ã®"Basic Information"ã®"App Credentials"ããSigning Secretï¼hexã§32æ¡ï¼ãã³ãã¼ãã¦ã
SIGNING_SECRET
ã«ããã
ãã®ãµã¼ããã¤ã³ã¿ã¼ãããããã¢ã¯ã»ã¹ã§ããã¨ããã§å®è¡ãã¾ãã å®é¨ã§ã¯ngrokãªã©ä½¿ãã¨ããããããã¾ããã
$ ruby ~/bot-server.rb ... == Sinatra (v4.0.0) has taken the stage on 4567 for development with backup from WEBrick [20XX-XX-XX XX:XX:XX] INFO WEBrick::HTTPServer#start: pid=XXXXXX port=4567
ããã¦ã"Event Subscriptions"ã®Request URLã§ãç«ã¦ããµã¼ãã®URLãå ¥åãã¾ãã ãã¾ãè¡ãã°"Verified"ã¨ãªãã¾ãã
Slackã§ãããã«å¯¾ãã¦@Sample Slack Bot Hello
ãªã©ã¨ã¡ã³ã·ã§ã³ãã¦ã¿ã¾ãããã
ãã¾ãè¡ã£ã¦ããã°ãHTTPãµã¼ãã®æ¹ã«çºè¨å
容ãåºã¦ããã¯ãã§ãã
"<@XXXXXXXXXXX> Hello" XXX.XXX.XXX.XXX - - [XX/XXX/20XX:XX:XX:XX +0900] "POST / HTTP/1.1" 200 - 0.0064
Socket Modeã使ãæ¹æ³
Socket Modeã¯ãRubyããWebSocketã§Slackã«æ¥ç¶ãã¦ããã·ã¥éç¥ãåãåãæ¹æ³ã§ãã publicãªHTTPãµã¼ããç¨æããªãã¦ããã®ã§ãéç¨ã¯æ軽ããããã¾ããã
æ®å¿µãªãããRubyã§gemãªãã§WebSocketã¯ã©ã¤ã¢ã³ãã使ãã®ã¯å¤§å¤ã§ãããããã調ã¹ã¾ããããæºè¶³ã§ããæ¹æ³ã¯ã¿ã¤ãããã¾ããã§ããã
調ã¹ããã¨ï¼ã¯ãªãã¯ããã詳細表示ï¼
WebSocketãããã³ã«ãæ±ãwebsocket gemã¯ããã§ãã¦ãã¦ãä¾åãã¼ããªã®ã§å¥½ã¿ã§ãã
ãã ãå®éã«éä¿¡ããgemã¨ãªãã¨ãeventmachineã ã£ããfaradayã ã£ããã巨大ãªgemã«ä¾åããã¡ã§ãã
ãã®ç¹websocket-client-simple gemã¯ããã®æã®ãã®ã«ä¾åããªãã¯ã©ã¤ã¢ã³ãã¨ããã³ã³ã»ããã¯å¥½ããªã®ã§ãããç´°ããã¨ããã§æ°ã«ãªããã¨ãå¤ãã£ãã§ã *1 ãããã好ã¿ã«åããã¦ç´ãããããªããSlackãããã«ç¹åãããããããªãã®ãèªä½ãããã£ã¦æ°åã«ãªãã¾ããã
net/httpãWebSocketããµãã¼ããã¦ããããããã®ã«ãªãã
ã¨ãããã¨ã§ãããããã¦websocket gemã®ã¿ã«ä¾åããslack_socket_mode_botã¨ããgemãä½ãã¾ãããããã使ãä¾ã ã示ãã¦ããã¾ãã
require "slack_socket_mode_bot" SLACK_BOT_TOKEN = "xoxb-..." SLACK_APP_TOKEN = "xapp-..." bot = SlackSocketModeBot.new(token: SLACK_BOT_TOKEN, app_token: SLACK_APP_TOKEN) do |data| if data[:type] == "events_api" && data[:payload][:event][:type] == "app_mention" event = data[:payload][:event] p event[:text] end end bot.run
å¿ è¦ãªè¨å®ã¯3ã¤ã§ãã
- Slack appã®è¨å®ç»é¢ã®"Socket Mode"ã§Enable Socket Modeãæå¹ã«ãã
- Slack appã®è¨å®ç»é¢ã®"OAuth & Permissions"ããBot User OAuth Tokenãã³ãã¼ãã¦ã
SLACK_BOT_TOKEN
ã«å ¥ããï¼`xoxb-ã§å§ã¾ããã®ï¼ - Slack appã®è¨å®ç»é¢ã®"Basic Information"ã®"App-Level Tokens"ãä½ã£ã¦ã
SLACK_APP_TOKEN
ã«ãããï¼xapp-
ã§å§ã¾ããã®ï¼
ãã¨ã¯ããã®ã³ã¼ããå®è¡ããã¨Slackã¨éä¿¡ãå§ãã¾ãã
$ ruby bot.rb
Slackã§ãããã«å¯¾ãã¦@Sample Slack Bot Hello
ãªã©ã¨ã¡ã³ã·ã§ã³ãã¦ã¿ã¾ãããã
ãã¾ãè¡ã£ã¦ããã°ãçºè¨å
容ãéç¥ãããp
ã§åºåãããã¯ãã§ãã
"<@XXXXXXXXXXX> Hello"
ã¡ãªã¿ã«ãSocket Modeã®WebSocketã¯ããã¾ã§ã¤ãã³ãéç¥ãåãåãããã ãã®ãã®ã§ããããããçµç±ãã¦chat.postMessage
ãªã©ã®APIãå¼ã¶ãã¨ã¯ã§ãã¾ããã
slack_socket_mode_botã§ã¯ãSlackSocketModeBot#call(method, data)
ã¨ããAPIãå¼ã¶æ¹æ³ããã¾ãã§ä»ãã¦ããã¾ããã
ã¾ã¨ã
ãªãã¹ãgemã«é ¼ããã«Rubyã§Slackã®ããããæ¸ãæ¹æ³ã説æãã¾ããã ããã§è¿°ã¹ãæ¹æ³ã¯ãRubyéçºè ã®Slack workspaceã§åãããããã¡ã§é·æééç¨ãã¦ãã¾ãã
ãã¡ããslack-ruby-client gemãªã©ã使ãã®ãããããã ã¨æãããæµæããªããªããããè³¢ãã¨æãã¾ãã ãã ãslack-ruby-client gemã¯Slack社謹製ã§ã¯ãªãã®ã§ããã¨ãã°ã¾ã Socket Modeã«å¯¾å¿ãã¦ããªãããã§ãã
ãªãgemã«é ¼ããªããã¨ããã¨ãä¾åãæ¸ããããã¨ããå人çãªå¥½ã¿ï¼ããããNot Invented Hereçå群ããï¼ãæ大ã®çç±ã§ãããSlackã¯ããã¨é »ç¹ã«APIãä»æ§å¤æ´ããã®ã§ãå¤å°é¢åã§ãSlackå ¬å¼ã®APIãç´æ¥å©ãã¦ããã»ããé·æçã«ã¯ã¡ã³ããã³ã¹æ§ãé«ãã®ã§ã¯ï¼ ã¨æã£ããæããªãã£ããã
å¤æ´å±¥æ´
- 06/24 22:00
OpenSSL.secure_compare
ãhalt 401, "{}"
ã使ãããã«ããï¼thanks @sora_h)
ç¶æ¿ã¯ãªãã§ãã¡ï¼
ããªãã¸ã§ã¯ãæåã®ç¶æ¿ã使ããªãã¨ãã主張ãåºã¾ã£ã¦ããããã§ãããªãã§ãã¡ã«ãªã£ããã§ããããã
ã¤ã³ã¿ã¼ãããã§è¦ããããç¶æ¿ã¯ãã¡ãã¨ãã主張ãããã¤ãçºãã¦ãå人ã¨è°è«ãã¤ã¤ãèãã¦ã¿ã¾ããã
ãã³ã¼ããèªã¿ã«ãããªãã
ç¶æ¿ãããã¨ãã¡ã½ããå¼ã³åºããå®éã«ã©ã®ã¡ã½ããå®ç¾©ãå¼ã³åºãã®ãåé¢ã§ããããªãã ãããã¬ã使ã£ã¦ã親ã¯ã©ã¹ã®ã¡ã½ããã«é£ãã ããåã¯ã©ã¹ã«é£ãã ãããã®ã追ããããªãã¨è¡ããªãã ã¤ãããã¨ãã主張ã
ãã£ã¡ãããããããããã§ãããããã¯ãé«åº¦ã«å ±éåãããã³ã¼ãã¯èªã¿ã«ãããã¨ããä¸è¬çãªå´é¢ãããªã大ãããããªã ãã¨ãã°ç¶æ¿ã®ä»£ããã«é«éé¢æ°ã使ãã¨ãé¢æ°å¼ã³åºããã©ã®ã¯ãã¼ã¸ã£ã«é£ã¶ãåé¢ã§ããããªããªãã ã²ã©ãã¨ã³ã¼ã«ããã¯å°çã«ãªã£ã¦ä½ãä½ããã«ãªãã¾ãã
ç¶æ¿ããã¨ããã«ã¾ããçç±ãæ³åããã¨ããã¹ã¦ã®ã¡ã½ããå¼ã³åºããããªã¢ã¼ãã£ãã¯ã«ãªãããã®ã¯ãèªã¿ã«ãããå¢ãã¦ãããã é«éé¢æ°ãªããé«éé¢æ°ã®å¼ã³åºãã ã注æããã°ãããããC++ ã® virtual ãã¼ã¯ã¼ãã¯æ£ããã£ãã®ã ï¼ï¼ï¼ã
ããããã°ãã¤ã³ã¿ã¼ãã§ã¤ã¹ã®ç¶æ¿ã¯è¯ãããå®è£ ã®ç¶æ¿ã¯ãã¡ãã¨ããæ´¾é¥ãè¦ããã¾ããããã®åé¡ã¯ãã¾ãå¤ãããªããã§ãã ãªããªããé£ã³å ã®åè£ãã親åã¯ã©ã¹ã ãããããã¤ã³ã¿ã¼ãã§ã¤ã¹ãå®è£ ããå ¨ã¯ã©ã¹ãã«ãªãã®ã§ãæªåããå¯è½æ§ãã
ãããç¥ã¯ã©ã¹ã«ãªãã
åºåºã¯ã©ã¹ã«ã¤ãã¤ã便å©ã¡ã½ãããçããã¦ãã¾ããæ°ã¥ãã°ä¾¿å©ã¡ã½ãããå¯ãéãããç¥ã¯ã©ã¹ãã«ãªã£ã¦ããã ãã®ä¾¿å©ã¡ã½ãããã¡ã¯ã誰ã使ã£ã¦ããããããªãã®ã§ãå¤æ´ã§ããªããªã£ã¦ãã¾ãã ã¤ãããã¨ãã主張ã
ååï¼å¯ãéãï¼ã¯ãããããã ã³ã³ãã¸ã·ã§ã³çã§åãåºããã¨æã£ã¦ããæ¢åã®ã¤ã³ã¹ã¿ã³ã¹å¤æ°ã«ã¢ã¯ã»ã¹ããå¿ è¦ããã£ããããã¨ãã¤ãã¤ãã¤ã³ã¹ã¿ã³ã¹ã¡ã½ããã«ãã¦ãã¾ã£ããã ã¤ã³ã¹ã¿ã³ã¹ã¡ã½ãããæé»çã« this/self ãåãåãã容æã«ã¤ã³ã¹ã¿ã³ã¹å¤æ°ã«ã¢ã¯ã»ã¹ã§ãã¦ãã¾ãã®ã¯ãç¶æ¿ãå¼·åãããããã¨ãããæ°ã¯ãã¾ãã
ãã ããç¥ã¯ã©ã¹ããä½ã£ã¦ãã¾ãè ã¯ãç¶æ¿ãç¦æ¢ããã¨ããã¹ã¦ãè©°ãè¾¼ãã åä¸ãç¥ã¢ã¸ã¥ã¼ã«ããè²æããããããªãã®ããªã
å¾åï¼å¤æ´ã§ããªããªãï¼ã¯ãã³ã¼ãå ±éåãã®ãã®ã®åé¡ã§ãç¶æ¿ä»¥å¤ã§ãèµ·ããæ°ããã¾ãã ããããªã¨ãããã使ããã¦ããã³ã¼ããå¤æ´ããã®ã¯ã©ãããã£ã¦ããã©ãã é¢æ°ã§åãåºãã¦ããmix-in ã«ãã¦ããã³ã³ãã¸ã·ã§ã³ã»å§è²ã§åãåºãã¦ããããã¯æ¬è³ªçã«ã¯ããããªãã
ç¶æ¿ã ã¨ç¹å¥ããã©ããªãçç±ãããã ãããããã¾ãæãã¤ããªãã£ãã ããããã¤ã³ã¹ã¿ã³ã¹å¤æ°ã®ã¢ã¯ã»ã¹æ§ç¢ºä¿ã®ããã«ãåãåºãããããããé¢ã¯ããããªãï¼
ãå¤ãªç¶æ¿ããã人ãããã
ã³ã¼ããåå©ç¨ããããã ãã«ã親åé¢ä¿ã¨ã¯è¨ããªãç¶æ¿ããã¦ãã¾ãããã°ã©ããããã æããã®ãæªç¨ãã¦ãã¾ãç¶æ¿ã¯ç¦æ¢ãã¹ãã ãã¨ãã主張ã
幸ããæå³çã«ãããªãã¨ãããããã°ã©ãã¯èº«è¿ã«ããªãã®ã§ãæåã¯ãã³ã¨ãã¾ããã§ããã ã§ããããããç¶æ¿é¢ä¿ãçã¾ããã·ããªãªã¯æãã¤ãã¾ããã
- ãã¨ãã¨
Clock
ã¨ããã¯ã©ã¹ã§ã¢ããã°æè¨ãå®è£ ãã¦ããã - ãã¸ã¿ã«æè¨ãå®è£ ããããªã£ãã
Clock
ãåºåºã¯ã©ã¹ã«ããAnalogClock
ã¯ã©ã¹ã¨DigitalClock
ã¯ã©ã¹ãæ´¾çãããã¨ããããã- ã¨æã£ããããã§ã«ããããªäººã
new Clock()
ãã¦ãããå ¨é¨new AnalogClock()
ã«æ¸ãæãã¦ãããï¼ ãã¼ãâ¦â¦ - äºææ§ãéè¦ãã¦ããããªã
DigitalClock extends Clock
ã§å¦¥åããã - ããã¸ã¿ã«æè¨ãã¢ããã°æè¨ãç¶æ¿ãããã¨ããçµæã ãè¦ã人ã¯ãæ¸ãã人ããã«ã ã¨æã£ã¦ãã¾ãã
ã¨ãããã¨ã§ãäºææ§ã®é æ ®ãªã©ã®äºæ ã§ãå¥å¦ãªç¶æ¿é¢ä¿ã¯ç¢ºãã«çããããã¨ãããã身ã«è¦ããããã
ãã ãããã¯ç¶æ¿ä»¥å¤ã§ãæ®éã«èµ·ããã
ã¢ããã°æè¨ãä½ã create_clock()
ã¨ããé¢æ°ãå
¬éãã¡ããã¨ãå¾ãã create_analog_clock()
ã«ããã®ã¯å¤§å¤ã
æªæ¥ã®ã¦ã¼ã¶ã¯ããªã㧠create_clock()
ãã¢ããã°æè¨ãªã®ããã«ãªã®ãã£ã¦æãã®ããããã¾ããã
ï¼æè¨ã®ä¾ããã£ããããªã人ã¯ãã¢ãã¯ããã¬ãã»ã«ã©ã¼ãã¬ãã¨ããã¬ãããã ä¸è¦§ãã好ããªä¾ãé¸ãã§èªã¿æ¿ãã¦ãã ããï¼
ç¶æ¿ããã¨ããã«åé¡ã ã¨ããããå¾ç¥æµã ã¨è¯ãè¨è¨ãè¦ããããããããªã£ã¦ããªããã¨ãæ°ã«ãªããããã®ããã é¢æ°ãªããã¯ãã¯ããã£ã¦æµãããã©ããªãã¸ã§ã¯ãæåã¯ãã°ãã«ãªã£ã¦ãã¦ãå¥å¦ãªè¨è¨ãè¦ããã¨ã«èããããªãã ã§ãããã§ç¶æ¿èªä½ãç¦æ¢ãããã¨ããã®ã¯ããã¯ããªãã¸ã§ã¯ãæåã¸ã®åå·çãªææ ã£ã¦æãããã¾ããâ¦â¦ã
ã¾ã¨ã
ãç¶æ¿ã¯ãã¡ãã¨ããçç±ã§ãããç¨åº¦å ±æããã®ã¯ãã¾ã®ã¨ãã2ã¤ã
- ãã¹ã¦ã®ã¡ã½ããå¼ã³åºããããªã¢ã¼ãã£ãã¯ã«ãªãããã®ã§ãã©ãã«é£ã¶ã常ã«æ³¨æãå¿ è¦ã§ãã³ã¼ãèªè§£ã大å¤ï¼ãã¾ã©ããªãã¨ãã£ã¿æ¯æ´ã§ãªãã¨ããªããããªï¼
- æé»çã« this ãåãåãã¤ã³ã¹ã¿ã³ã¹ã¡ã½ããã¯ä¾¿å©ããã¦æªç¨ãããããå¯ãéãã®ãç¥ã¯ã©ã¹ãã«ã¤ãªãããã¡ï¼ãã ãç¶æ¿ç¦æ¢ã§æ¬å½ã«è§£æ±ºãããã¯ããããªãï¼
ãç¶æ¿ã®åé¡ã¯ãããªäºæ«ãªãã¨ãããªãï¼ ãã£ã¨å¤§ããåé¡ã ï¼ãã¨ãã人ããããããã²ããããæãã¦ä¸ããã
ãã©ã¦ã¶ã§Rubyãåãã夢
ä½ã«ä½¿ãããã§ããªããã©ãã¨ã«ãããã©ã¦ã¶ã§ Ruby ãåããããã£ããã§ãã
ãã®å¤¢ããã¤ãã«ããªã£ãæ°ããã¾ãã
é·å¹´ã®å¿µé¡ã ã£ã Emscripten 㨠xterm.js ã§ãã©ã¦ã¶ã§ irb ãåãããã¤ãã¤ãã«ï¼ä¸å¿ï¼ã§ããhttps://t.co/ubentOzj7p
— Yusuke Endoh (@mametter) 2024å¹´1æ27æ¥
æ¯ãè¿ã£ã¦ã¿ãã¨ãããã«æ¥ãã¾ã§ 6 å¹´ãããã£ãããã§ããã¡ãã£ã¨å¬ãããªã£ãã®ã§çµç·¯ãæ¸ãæ®ãã¾ãã
Emscripten 㧠Ruby ããã«ããã
2018 å¹´ããµã¨æãç«ã£ã¦ãEmscripten 㧠Ruby ããã«ãã§ããããã«ãã¾ããã
Emscripten ã¯ãè¦ããã« C/C++ ããã°ã©ã ã JavaScript ã Wasm ã«å¤æãã¦ãããã³ã³ãã¤ã©ã§ããC ã§æ¸ããã Ruby ã Emscripten ã§ãã«ãããã°ããã©ã¦ã¶ã§åã Ruby ãä½ããã¯ãã
æå¤ã¨å¾®ä¿®æ£ã ã㧠miniruby *1 ããã«ãã§ãã¦ãç°¡åãªã³ã¼ããªãåãããããã«ãªãã¾ããã
å®å®ãã Emscripten'ed Ruby ãã¡ã³ããã³ã¹ãã
ãã ãã¡ãã£ã¨åã£ãã³ã¼ããèµ°ãããã¨è½ã¡ããåºãã£ãããã¦ãã¾ã¨ãã«ä½¿ããã¯ãªãªãã£ã«ã¯ã§ãã¾ããã§ãããã¾ããRuby ã Emscripten ãå¤ãã£ã¦ããã®ã§ããã°ããããããã«ãã§ããªããªã£ã¦ãã¾ãã¾ããã
ãããããªãã®ã§æ¾ç½®ãã¦ããããkateinoigakukun ããã£ã¦ããã¹ã¼ãã¼ããã«ã¼ããã£ããã¨ç¾ãã¦ãRuby ã® Wasm/WASI 対å¿ãã¯ããã¦ããã¾ãããRubyKaigi 2022ã®ãã¼ãã¼ãã¯è¨æ¶ã«æ°ããã§ããã
kateinoigakukun ããã¯èªåã¨éã£ã¦ Wasm ã«ã¡ããã¨è¶ 詳ããã®ã§ãä¸å®å®ãªæåã«å¯¾ãã¦å ´å½ããçã«å¯¾å¿ããã®ã§ã¯ãªããã¾ããã«æ ¹æ¬åå ã調ã¹ã¦æ¹åãããã¨ããã£ã¦ããã¾ãããã¾ãããã«ãã·ã¹ãã ã®ã¡ã³ããã³ã¹åãé«ããWasm/WASI Ruby ã® nightly ãã«ããé å¸ãã¦ãããããã«ãªãã¾ããã
katei ããã®èå³ã¯ WASI *2 ã®ã¯ãã§ããããªãã Emscripten ãã«ããæä¾ãã¦ããã¾ããããã®ãã¾ãã«ãããããããå®å®ç㪠Ruby ã® Emscripten ãã«ããç¡æã§å¾ãããããã«ãªã£ãã®ã§ãããæé«ã
Emscripten ããã°ã©ã ã xterm.js ã«ã¤ãªã
ãã©ã¦ã¶ã§ Ruby ãåãããã«ãªã£ãã®ã§ãããã¤ãã¢ããªãæ¸ãã¾ããã楽ããã
ruby-puzzles-2022.cookpad.tech mame.github.io
ãã ãå¥ã« Ruby ã§ãã©ã¦ã¶ã¢ããªãæ¸ãããã£ãããã§ã¯ãªããã§ããããã£ã±ã REPL ãåãããããä½ã«ä½¿ãããã§ããªããã©ã
ãã®ããã«ã¯ããã©ã¦ã¶ã§åã端æ«ã«ã¤ãªã㧠irb ãåãããªãããããªãããã©ã¦ã¶ã§åã端æ«ã¨ãã¥ã¬ã¼ã¿ã«ã¯ xterm.js ãããããã㯠vscode ã§ã使ããã¦ããè¶ å®å®ã©ã¤ãã©ãªãªã®ã§ããã¨ã¯ Emscripten'ed Ruby ã¨ã¤ãªãã ãã§ããã
ãããã¾ã大å¤ã§ããã
Emscripten ããã°ã©ã ã«éããªãã®ã§ããã端æ«ã¨ãã¥ã¬ã¼ã¿ã¨ããã°ã©ã ã¯é常ãç´çµãã¦ãã¾ãããLinux ã§ããC ããã°ã©ã ã printf("Hello\n");
ã¨ããã¨ã端æ«ã¨ãã¥ã¬ã¼ã¿ã«ã¯ Hello\r\n
ã¨ããæååã渡ããã¾ãã\r
ãæ¿å
¥ããã¦ãããã¨ã«æ³¨æããããæ¿å
¥ããã®ã¯ãããã°ã©ã ã§ã端æ«ã¨ãã¥ã¬ã¼ã¿ã§ããªããå®ã¯ Linux ã«ã¼ãã«ã§ããLine discipline ã¨ããæ©è½ãããã§ãã*3
xterm.js 㧠Linux ããã°ã©ã ãåããå ´åãnode-pty ã¨ããå®çªã©ã¤ãã©ãªããããvscode ãªã©ãããã使ã£ã¦ããããã§ãããããã㯠Linux ã® pty ã®ã©ãããªã®ã§ããã©ã¦ã¶ã§ã¯åãã¾ãããEmscripten ã®ããã«ããã©ã¦ã¶ã®ä¸ã§åã pty ãã»ããã¨ãã声ã¯ã¡ãã»ãããããã§ããããä½ã£ã人ã¯ããªãããã§ããã
ãªããªãä½ããã£ã¦ãã¨ã§ãxterm-pty ã¨ãã Emscripten ããã°ã©ã ã¨ã¤ãªãããã® xterm.js ã¢ããªã³ãä½ãã¾ããã
ããã¯è¦ããã« Line discipline ãæ°åã§å®è£ ãããã®ã§ãããã©ã¦ã¶ã§ Ruby ãåããããã¨æã£ããããã¤ã®ã¾ã«ã Line discipline ã JavaScript ã§å®è£ ãã¦ããã
ã¾ããxterm-pty 㧠Vim ãåããã¨ãã¯ãªããªãã®éææã§ãããVim ã®ãã¢ã¯âãåç §ã
ãªããVim ã Emscripten ãããã¨èªä½ã¯æ¢åºã§ããããã¡ã㯠Vim ã«ç¹åããã¬ã³ãã©ãèªä½ããã®ã«å¯¾ãããã¡ã㯠xterm.js ã¨ã¤ãªãã§åãããã¨ãããæ°è¦æ§ãæ±ç¨çãªã®ã§ Vim 以å¤ã® CUI ããã°ã©ã ãåãã¾ãã詳ããã¯ãã¢ãåç §ã
xterm-pty ãã¾ã¨ãã«ãã
ã§ãirb ãåããããã«ä½ã£ã xterm-pty ã§ããããå®éã« irb ã¨æºè¶³ã«ã¤ãªãã«ã¯èª²é¡ãããã¾ããã
Line discipline ã¯ãIO ã®ããåãã ãã§ãªããã·ã°ãã«ãæããå½¹å²ãããã¾ããCtrl+C ãæ¼ãããã¨ãã« SIGINT ãæããã®ã¯ãå®ã¯ Line discipline ã§ããããã Emscripten ããã°ã©ã ã«ã¯ã·ã°ãã«ã¨ããæ¦å¿µãã®ãã®ããªãã£ãã®ã§ãæããããããã¾ããã§ããã
ã¾ããxterm-pty 㨠Emscripten ããã°ã©ã ã¨ã¤ãªãé¨åã極ãã¦ä¸å®å®ã§ãããEmscripten ã©ã³ã¿ã¤ã ãã¢ã³ãã¼ãããã㦠read/write/select ãªã©ã®ã·ã¹ãã ã³ã¼ã«ãã¤ã³ã¿ã¼ã»ãããã¦ããã®ã§ãEmscripten ãã¡ãã£ã¨å¤æ°åãå¤ããã¨åããªããªãã
ãããªããã§ããããããªãæ¾ç½®ãã¦ããã®ã§ããããªãã Ingvar Stepanyan ã£ã¦ãã Emscripten ã«è¶ 詳ããã¹ã¼ãã¼ããã«ã¼ããã£ããã¨ç¾ãã¦ããEmscripten ã«ã·ã°ãã«ãå®è£ ããããã¢ã³ãã¼ãããã§ãªã Emscripten ã®ãã©ã°ã¤ã³çã« xterm-pty ã使ããããã«ãããã¨è¨ããã»ã¨ãã©ä½ãç´ãã«è¿ã PR ããããã®ã§ãçªå¦è§£æ±ºãã¾ãããæé«ã
ã¤ãã« Ruby ã® REPL ããã©ã¦ã¶ã§åã
å·æ°ããã xterm-pty ããªãªã¼ã¹ããã®ã§ãçµã¿åãã㦠irb ãåããã¦ã¿ããããªãã¨ä¸åã®ããããå¿ è¦ã¨ããã«åãã¾ããããããããããããã6 å¹´åã¨æ¯ã¹ãã¨å¥ä¸çã
è£å®ãåºãããã¤ã¼ã¹ã¿ã¼ã¨ãã°ã®ã¢ãã¡ã¼ã·ã§ã³ãåãã¾ãã
twitter.comemscripten irb ã§ã¤ã¼ã¹ã¿ã¼ã¨ãã°ãå®å®çã«åãããã«ãªã£ã¦ããhttps://t.co/ubentOzj7p pic.twitter.com/wkRb2DxYeF
— Yusuke Endoh (@mametter) 2024å¹´1æ31æ¥
ããã¼ããããè¦ããã£ããã§ããã夢ãããªã£ãç¬éãä½ã«ä½¿ãããã§ããªããã©ã
ã¾ã¨ã
ãã©ã¦ã¶ã§ Ruby ãåãã夢ãããªãã¾ãããããªã£ãããããªãããªã
ã¾ããThread.new ãåããªãã¨ããæ¡å¼µã©ã¤ãã©ãªããã¼ãã§ããªãã¨ããã¾ã ã¾ã 課é¡ã¯ããããã§ããã
é©å½ãªãã®ãä½ã£ã¦æ¾ç½®ãã¦ããã¹ã¼ãã¼ããã«ã¼ãã¡ãç´ãã¦ããã人çã ã£ãã®ã§ããããªãã¹ã¼ãã¼ããã«ã¼ã®ç»å ´ãå¾ ã¡ããã
ãã¾ã
å®ã¯ãkateinoigakukun ããèªèº«ã irb.wasm ããã£ã¦ãã¾ãã
ãã㯠Emscripten ã§ã¯ãªã WASI ã§å®ç¾ããã¦ãã¾ãã
irb.wasm 㯠jquery-terminal ã使ã£ã¦ããããã§ãè£å®ãªã©ã¯åºã¾ãããããRubyWorld Conference 2022 㧠picoruby/picoirb ãçºè¡¨ãã¦ã hasumikin ããã«ç¸è«ããã irb.wasm 㧠xterm.js ã使ãã¢ã¼ããå®è£ ãã¦ãããã®ã§ããã£ã¡ãªãè£å®ãåºã¾ãããã ãpty ãã¾ããã«æ¨¡å£ãã¦ããããã§ã¯ãªããirb ã reline ã«ã¢ã³ãã¼ãããããã¦ã¦ã©ãã«ããã¦ãããããªã®ã§ãåç¾æ§ã¯ããå¾®å¦ããããã¨ãã°ä¾ã®ã¤ã¼ã¹ã¿ã¼ã¨ãã°ã¯ï¼ã¾ã ï¼åããªãã£ããirb.wasm 㧠xterm-pty ã使ãããã«ããã¨ããããã ãã©ãã§ããã®ããªï¼
*1:Ruby ã®ãã«ãæã«ä¸éçã«ä½ãããç°¡æ㪠Ruby ã¤ã³ã¿ããªã¿ãæ¡å¼µã©ã¤ãã©ãªããã¼ãã§ããªããªã©ãå¶éãããã
*2:WASI ã¯ãWasm ã®ãã¼ã¿ãã«ãªã·ã¹ãã ã¤ã³ã¿ã¼ãã§ã¤ã¹ãEmscripten ããã©ã¦ã¶ç¹åã® Wasm ãåºåããã®ã«å¯¾ããWASI ã«åºã¥ãã Wasm ã¯ãã©ã¦ã¶ã ãã§ãªãé å¸ç¨å®è¡ãã¡ã¤ã«ãã¨ãã¸ã³ã³ãã¥ã¼ãã£ã³ã°ç°å¢ãªã©ã§å ±éãã¦ä½¿ããã
*3:pty ã¨ã termios ã¨ãã®ãã¼ã¯ã¼ãã®ã»ãããããããããããpty 㯠Line discipline ã§ç¹ããããã¹ã¿ã¼ã»ã¹ã¬ã¼ãã®ãã¢ã§ãtermios ã¯ã¹ã¬ã¼ãå´ãã Line discipline ãå¶å¾¡ããããã® API ãã ã¨æã£ã¦ã¾ãããæ£ç¢ºãªå®ç¾©ã¯èªä¿¡ãªãã
Rubyã®å ¨ãã¼ã¸ã§ã³ã§åãQuine
ãã®ããã°ã©ã ã¯ãRuby 0.49ï¼1994å¹´ãªãªã¼ã¹ï¼ããRuby 3.2.1ï¼ä»æãªãªã¼ã¹ï¼ã¾ã§ãç¾å¨ç¢ºèªããã¦ãããã¹ã¦ã®CRubyã§åä½ããQuineã§ãã
eval($s=("t='eval($s=('+d=34.chr;s=3 2.chr+$s*i=8;v=$VERSION||eval('begin;v=V ERSION;rescue;v||RUBY_VERSION;end');f=('?'*8 +'A|'+'?'*20+'G?c'+'?'*15+'A@CXx@~@_`OpGxCxp@~pO xS|O~G?c?q?xC`AP|q?x_|C_xC_xO@H@cG?G?qA|_|_`GCpOxC|H NFccqq@`_|OF@`?q?x_@x_x_`GB`O``O~G?C@qCxCxP@D@|G~C?pO|C? pO|C?AP|A~HNN`ccxC|Q@L@B"+"GpGpc@p?x_`GB`???_@FO|OB@ xC|P`@?c?q?HPx@~@_`G@`????@L^`?q?x?xq@|_|O~GC` xA~@_@GBD').unpack('c*');w=4+v.length*u= 15;r=10.chr;j=0;while-24+w*u>i=1+i ;x=i%w;x>0||t=t+d+'+'+r+d;k= i/w%12>2&&x%u>3&&x%u+i /w*11-34+('-._'. index(c=v[ x/u,1] )||c.hex +3)*99| |0; k=f [k/6 ][k% 6]; t=t +s[ k*j =k+ j,1 ]end;pr int (t+ d+' ).s pli t.j oin [0, 609 ])# Y.E. '+r) ").split .join)#
ããã°ã©ãã³ã°è¨èªRuby 30å¨å¹´è¨å¿µã¤ãã³ãã§LTçºè¡¨ãããã®ã§ããã³ã¼ãã¯GitHubã«ç½®ãã¾ããã
åä½æ¹æ³
å ¨ãã¼ã¸ã§ã³ã§å®è¡ããã«ã¯ãrubylang/all-rubyã¨ããdocker imageã使ã£ã¦ãã ããã
$ wget https://raw.githubusercontent.com/mame/all-ruby-quine/main/all-ruby-quine.rb $ docker run --rm -ti -v `pwd`:/src rubylang/all-ruby
./bin/ruby-0.49 /src/all-ruby-quine.rb
ã¨ããã¨ãruby 0.49ã§å®è¡ã§ãã¾ãã
# ./bin/ruby-0.49 /src/all-ruby-quine.rb eval($s=("t='eval($s=('+d=34.chr;s=32.chr+$s*i=8;v=$VERSION||eval"+ "('begin;v=VERSION;rescue;v||RUBY_VERSION;end');f=('?'*8+'A|'+'?'"+ "*20+'G?c'+'?'*15+'A@CXx@~@_`OpGxCxp@~pOxS|O~G?c?q?xC`AP|q?x_|C_x"+ "C_xO@H @cG?G?qA|_|_`GCpOxC|HNFcc qq@`_|O F@`?q"+ "?x_@ x_x _`GB`O``O~G?C@qCxCxP@D @|G~C? pO| C?pO"+ "|C?A P|A~H NN`ccxC|Q@L@BGpGpc@p? x _`GB`? ??_@F O|OB"+ "@xC| P`@?c ?q?HPx@~@_`G@`????@L ^` ?q?x?x q@|_ |O~G"+ "C`xA ~@_@G BD').unpack('c*');w =4+ v.lengt h*u="+ "15;r =10.c hr;j=0;while-24+w*u >i= 1+i;x=i%w;x>0| |t=t"+ "+d+' +'+r+ d;k=i/w%12>2&&x%u>3 &&x%u+i/w*11 -34+"+ "('-. _'. index(c= v[x/u,1])||c.h ex+3)* 99|| 0;k="+ "f[k/6] [k%6];t=t+ s[k*j=k+j,1]en d;print (t+d+"+ "').split.join[0,609])#Y.E.'+r)t='eval($s=('+d=34.chr;s=32.chr+$s"+ "*i=8;v=$VERSION||eval('begin;v=VERSION;rescue;v||RUBY_VERSION;en"+ "d');f=('?'*8+'A|'+'?'*20+'G?c'+'?'*15+'A").split.join[0,609])#Y.E.
åæ§ã«ã./bin/ruby-3.2.1 /src/all-ruby-quine.rb
ã¨ããã°ruby 3.2.1ã§å®è¡ã§ãã¾ãã
# ./bin/ruby-3.2.1 /src/all-ruby-quine.rb eval($s=("t='eval($s=('+d=34.chr;s=32.chr+$s*i=8;v=$VERSION||eval('begin;v=VERSI"+ "ON;rescue;v||RUBY_VERSION;end');f=('?'*8+'A|'+'?'*20+'G?c'+'?'*15+'A@CXx@~@_`Op"+ "GxCxp@~pOxS|O~G?c?q?xC`AP|q?x_|C_xC_xO@H@cG?G?qA|_|_`GCpOxC|HNFccqq@`_|OF@`?q?x"+ "_@x_x _`GB`O``O~G?C@qCxCxP@D @|G~C?pO|C?pO|C?AP|A~HN N`ccxC|Q"+ "@L@B GpGp c@p?x_`GB`???_@FO|OB @xC|P `@?c?q?HPx@~@_`G@`??? ?@L^`?q?"+ "x?xq@|_|O~GC `xA~@_@GBD').unpack('c*');w =4+v.length*u=15;r=1 0 .chr;j=0"+ ";while-24+w *u>i=1+i;x=i%w;x>0||t=t+d+'+ '+r+d;k=i/w%12>2&&x%u>3 &&x%u+i/"+ "w*11-3 4+('-._'.index(c=v[x/u,1])| |c.hex+3)*99||0;k=f[k/6] [k%6];t="+ "t+s[k*j=k+j ,1]end;print(t+d+').spli t.join[0,609])#Y.E.'+r)t=' eval($s="+ "('+d=34.chr; s=32.chr+$s*i=8;v=$VE RSION||eval('begin;v=VERSION ;rescue;"+ "v||R UBY_ VERSION;e nd');f=( '?'*8+'A|'+'?'* 20+'G?c'+'?' *15+'A@C"+ "Xx@~@ _`OpGxCxp@ ~pOxS|O~ G?c?q?xC `AP|q?x_| C_xC_"+ "xO@H@cG?G?qA|_|_`GCpOxC|HNFccqq@`_|OF@`?q?x_@x_x_`GB`O``O~G?C@qCxCxP@D@|G~C?pO|"+ "C?pO|C?AP|A~HNN`ccxC|Q@L@BGpGpc@p?x_`GB`???_@FO|OB@xC|P`@?c?q?HPx@~@_`G@`????@L"+ "^`?q?x?xq@|_|O~GC`xA~@_@GBD').unpack('c*');w=4+v.length").split.join[0,609])#Y.E.
./bin/ruby-3.2.0 /src/all-ruby-quine.rb | ./bin/ruby-0.49
ã§ãruby 3.2.0ã®åºåãruby 0.49ã§åããã¾ããéãå¯ã
å
¨ãã¼ã¸ã§ã³ã§åããããã£ãã ./all-ruby all-ruby-quine.rb
ã¨ãã¦ãã ããã
Rubyã®å ¨ãã¼ã¸ã§ã³ã§åãããã°ã©ã ã®ä½ãæ¹
ãã¶ã誰ã®å½¹ã«ãç«ã¡ã¾ãããããã®Quineãæ¸ãã®ã«å¾ãããç¥è¦ãã¾ã¨ãã¦ããã¾ãã
ãããã¯ã¯ä½¿ç¨ä¸å¯
ruby 0.49ã®ãããã¯ã¯ãdo ary.each using x ... end
ã¨ããè¨æ³ã ã£ãããã§ããç¾ä»£ã§è¦ã ary.each {|x| ... }
ã ary.each do |x| ... end
ã®ãããªãããã¯ã¯ããã¾ãããæ§å¼ã®ææ³ã¯ç¾ä»£ã®Rubyã§ã¯syntax errorã«ãªãã®ã§ãå
¨ãã¼ã¸ã§ã³ã§åããã«ã¯ãããã¯ã¯ä½¿ãã¾ãããwhile
æãªã©ã§ããã°ãã¾ãããã
x += 1
ã¯ä½¿ç¨ä¸å¯
ruby 0.49ã«ã¯ x += 1
ã x ||= 1
ã®ãããªæ§æãããã¾ãããx = x + 1
ãªã©ã¨æ¸ãä¸ãã¾ãã
ä¸é æ¼ç®åã¯ä½¿ç¨ä¸å¯
ruby 0.49ã«ã¯ cond ? a : b
ãã¾ã ããã¾ãããif
æã¯ããã¾ãããã¡ãã£ã¨é·ãã®ã§ cond && a || b
ãªã©ã¨ããã¨ãããã㧠ãããã
大ããæååãªãã©ã«ã¯ä½¿ç¨ä¸å¯
ruby 0.49ã§å¤§ããï¼700ãã¤ããããï¼ã®æååãªãã©ã«ãä½ãã¨SEGVããããã§ãããæååã®é£çµã使ã£ã¦åé¿ãã¾ããã¡ãªã¿ã«æååã®é£çµã§åãã¨ãããã¨ã¯ãå ¨ãã¼ã¸ã§ã³ã§GCãããããå®å®ãã¦åãã¦ããã£ã¦ãã¨ãªã®ã§ãçµæ§ããããã¨ã§ãã
%-è¨æ³ã®ãªãã©ã«ãå¼å±éã¯ä½¿ç¨ä¸å¯
ãã®æã®Quineã§é常ã«ä¾¿å©ãª %(...)
ã¨ããæååãªãã©ã«ã¯ãruby 0.49ã§ã¯æªå®è£
ã§ããString#split
ãArray#join
ãããã®ã§ãã³ã¼ãã®ã¢ã¹ãã¼ã¢ã¼ãå㯠eval(s="...ã¡ã¤ã³ã®ã³ã¼ã...".split.join)
ã¨ããã°å¯è½ã§ãã
ãã¨ã"#{expr}"
ããªãã®ã§æ³¨æãããã°ã£ã¦æååé£çµãã¾ãããã
evalã®ä¸ã§ã¡ã½ããå®ç¾©ã¯ä½¿ç¨ä¸å¯
ruby 1.3.1-990324 ã§ã¯ eval("def foo; end")
ãªã©ã¨ãã㨠nested method definition
ã¨ããä¾å¤ã«ãªãã¾ãããããããã°ãªãã§ããããããã«ããå
¨ãã¼ã¸ã§ã³ã§åããããã«ã¯ä½¿ãã¾ããã
evalã®ä¸ã§ã³ã¡ã³ãã¯ä½¿ç¨ä¸å¯
ruby 1.1d0 㧠eval("1#")
ãªã©ã¨ããã¨SEGVãã¾ããééããªããã°ã§ãããã³ã¡ã³ãã使ãã®ã¯é¿ãã¾ãããã
evalã§ãã¼ã«ã«å¤æ°ãåç §ããã®ã¯ä¸å¯
åç¾æ¡ä»¶ãããå¾®å¦ãªã®ã§ãããruby 0.51ãªã©åæãã¼ã¸ã§ã³ã§ã¯æ¬¡ã®ã³ã¼ãã§SEGVãã¾ãã
s = "hello"; eval("print(t = s)")
eval
ã§å¤ã®ãã¼ã«ã«å¤æ°ãèªã¿åºãã¨ããã«ãã°ãããããã§ãããã°ãã¼ãã«å¤æ°ã使ãã¨å®å®ãã¦åãã¾ããã
$s = "hello"; eval("print(t = $s)")
str[idx]ã«æ³¨æ
Ruby 1.8ã¾ã§ãstr[idx]
ã¯idxçªç®ã®ãã¤ããæ´æ°ã§è¿ãã¦ãã¾ãããã1.9ããã¯1æåã®æååã«å¤ãã£ã¦ãã¾ãããªã®ã§str[idx]
ã¯ä½¿ããªãã®ãç¡é£ã§ããã©ããã¦ã使ãããã£ããããã¨ãã°æ¬¡ã®ããã«æ¸ãã°è¯ãã§ãããã
ch="ABC"[1]; "@"[0] == 64 && ch=[ch].pack("C*")
ããã§å
¨ãã¼ã¸ã§ã³ã§ ch == "B"
ã«ãªãã¾ãããã¤ã³ãã¯ã"@"[0]
ãæ´æ°ãã©ãããè¦ã¦åå²ããã¨ããã§ãï¼?@ == 64
ã§ãããï¼ãåããªãã¦ããã£ãã§ããã
å©ç¨å¯è½ãªçµã¿è¾¼ã¿ã¡ã½ããã«æ³¨æ
å½ç¶ã§ãããæã®Rubyã¯ä»ã»ã©çµã¿è¾¼ã¿ã¡ã½ãããå å®ãã¦ããªãã®ã§ãä½ãå©ç¨å¯è½ããæ éã«è©¦ãå¿ è¦ãããã¾ããã¨ã¯ãããruby 0.49ã®æç¹ã§æå¤ã¨å¤ãã§ããç¾ä»£ã®çµã¿è¾¼ã¿ã¡ã½ããã®åå以ä¸ã¯ãã§ã«ããããããªãããªã
ã©ããªã¡ã½ããããããã¯ãruby 0.49ã«å梱ããã¦ããspecã¨ãããã¡ã¤ã«ã便å©ã§ãããã¤ã¦ãRubyã«ã¯ããã¥ã¡ã³ãããªããã¨è¨ããã¦ããã®ã¯ãªãã ã£ãã®ãã
Rubyã®ãã¼ã¸ã§ã³çªå·ãåºåããããã°ã©ã
all-ruby-quineã®èã¯ã¤ã³ã¿ããªã¿ã®ãã¼ã¸ã§ã³çªå·ãåå¾ããã¨ãããªã®ã§ããããããçµæ§ hacky ã§ããããã®é¨åã ãåãåºãã次ã®ã³ã¼ãããåRubyãã¼ã¸ã§ã³ã§ã©ã®ããã«è§£éãããã説æãã¦ããã¾ãã
print($VERSION||eval('begin;v=VERSION;rescue;v||RUBY_VERSION;end'))
ãã®ã³ã¼ããåãã¼ã¸ã§ã³ã§ã©ã®ããã«è§£éããããã説æãã¦ããã¾ãã
0.49 .. 0.65
ãããã®ãã¼ã¸ã§ã³ã§ã¯ $VERSION
ãå®ç¾©ããã¦ãã¾ãããã£ã¦ã$VERSION || ...
ã®å¾åã¯è©ä¾¡ãããããã®ã¾ã¾ $VERSION
ãè¿ãã¾ããå¾åã§eval
ã使ã£ã¦ããã®ã¯ããããã®ãã¼ã¸ã§ã³ã§ã¯ begin; ...; end
ã®æ§æãã¾ã åå¨ããããã®ã¾ã¾æ¸ããã syntax error ã«ãªãããã§ãã
0.69 .. 0.76
ãããä¸çªãããããã§ãããããã®ãã¼ã¸ã§ã³ã§ã¯ $VERSION
ãå®ç¾©ããã¦ããããå®æ°ã®VERSION
ãå®ç¾©ããã¦ãã¾ããå¾è¿°ãã1.9.0ããã¯RUBY_VERSION
ã«ãªãã¼ã ãããã®ã§ãããRUBY_VERSION
ãåç
§ããã¨ä¾å¤ã«ãªã£ã¦ãã¾ãã®ã§ãå°ã工夫ãå¿
è¦ã§ãã次ã®ããã«ãã¾ããã
begin v = VERSION rescue v || RUBY_VERSION end
rescue
ã®ã¤ã³ãã³ããããããã®ã¯æå³çã§ããã¨ããã®ãããããã®ãã¼ã¸ã§ã³ã§ã¯ä¾å¤ææãã¼ã¯ã¼ã㯠resque
ã§ãããrescue
ã¯ãã ã®ã¡ã½ããå¼ã³åºãã¨è§£éããã¾ããããªã undefined method ã¨ã©ã¼ã«ãªãã®ã§ã¯ï¼ãã¨æãããããã¾ãããã幸ããªãã¨ã«ãããã®ãã¼ã¸ã§ã³ã§ã¯ãæªå®ç¾©ã¡ã½ããå¼ã³åºãã¯é»ã£ã¦ nil
ãè¿ããã¨ãããã¯ã¼ã®ããä»æ§ã§ãããã£ã¦ãå¤æ° v
ã« VERSION
ã®ä¸èº«ã代å
¥ããããã¨ãv || RUBY_VERSION
ã®å¾åã¯è©ä¾¡ãã·ã§ã¼ãã«ãããããã®ã§ãç¡äº VERSION
ãè¿ããã¾ãã
0.95 .. 1.8.7-p374
ãããã®ãã¼ã¸ã§ã³ã§ã¯ VERSION
ãå®ç¾©ããã¦ãã¾ãã0.95㧠resque
ã rescue
ã«å¤ãã£ãã®ã§ãç´ ç´ã« v = VERSION
ã ãè©ä¾¡ããã¦å¤ãè¿ãã¾ãã
1.9.0 ..
VERSION
å®æ°ãåé¤ãããã®ã§ãv = VERSION
㯠NameError
ãæãã¾ããããã rescue
ã«ãã£ã¦è£è¶³ãããã®ã§ãRUBY_VERSION
ãè©ä¾¡ããã¦å¤ãè¿ãã¾ãã
ææ³
ãªã«ããé©ããã®ã¯ãruby 0.49ã®æç¹ã§ããªãRubyã«ãªã£ã¦ãããã¨ã§ããç¾ä»£ã®Rubyã®æ©è½ã®åå以ä¸ã¯ãã§ã«ããããã
ããã¦ãããããã»ã¨ãã©å¤ãã£ã¦ãªãã®ããããããã®Quineç¨åº¦ã«éèªæãªããã°ã©ã ãæ¸ãããããã«ãæ¬è³ªçãªéäºæããªããããã¯ãããã¨ãã¯ãããã¾ã§ã§ããã¨ã¯æã£ã¦ã¾ããã§ããã
ãRubyã¯æªå®æã ã£ãã®ã§éçºååè ãããããç¾ãã¦ããããOSSã¨ãã¦ã®æåã«ã¤ãªãã£ããã®ããã«matzãèªã£ã¦ããã®ã¯ããã¨æåã§ãããããã¯ãã£ã¦ããæåã®æç¹ã§ããªãå®æãã¦ãããã¨ãããã¦ãããããã¬ãªããã¨ããæåããOSSã®ç§è¨£ãªã®ã§ã¯ãªããã¨ããæ°ããã¾ãã
ãããããåæãå«ãã¦åãªãªã¼ã¹ã®å質ãé常ã«é«ãããã°åé¿ã®ãã¯ããã¯ãããããæ¸ããã®ã§è¨ã£ã¦ããã¨ã¨éãã¨æãããããã¾ããããè¨èªå¦çç³»ã£ã¦å¤ãã®äººãå®æ¦ã§ä½¿ã£ã¦ã¯ããã¦ã¾ã¨ãã«ãªããã®ãªãã§ããããä¿¡ããããªã人ã¯quine-relayãä½ã£ã¦ã¿ãã¨ããã§ããä¸ã®ãã¤ãã¼è¨èªå¦çç³»ãã¡ãããã«ãµã¤ãã®ã³ã¼ãã§ãããSEGVããã¨ããè´å½çã«æ©è½ã足ããªãã¨ããããããèµ·åãããªãã¨ãããããã¾ãããããèããã¨ãã¦ã¼ã¶ãã»ã¨ãã©ããªãã£ãåæã§ãRubyã®åãªãªã¼ã¹ã®å質ãããã¾ã§é«ãã®ã¯é©ç°çã§ãã
ã¨ãããã¨ã§ãmatzã¯ãããï¼ã¨ãããã¨ãä½æã§ããéã³ã§ãããã ããPythonã¨ãä»ã®è¨èªã§ãããã¨ããã¨æãã¾ãã
è足
ruby 0.49以åã®ã³ã¼ããçºæããã¾ããããã«ã
Goè¨èªã®ä¸æº
ã¡ãã£ã¨ãã¤ããªé å¸ããããã¼ã«âããã£ãã®ã§ãGoè¨èªã¨æ¯ãã¾ããã
ã»ã¼ã¯ããã¦Goã使ã£ãã®ã§ãã«ããã»ã©èªããããæ³åã«å¾ã£ã¦ãGoè¨èªã®ææ³ãæ¸ãã¾ãã
æ°ããè¨èªã«ãµããã¨ãã¯ãã§ãããã¨ã«ã¯æ°ã¥ãã«ãããã§ããªããã¨ã«æ°ã¥ããããã®ã§ãä¸æºãå¤ãã§ãã主ãªæ¯è¼å¯¾è±¡ã¯RubyãCè¨èªãJS/TSãRustãããã§ãã
ããã£ãã¨ãã
- ã²ã¨ãã¨ã§è¨ãã°ã便å©ã«ãªã£ãCè¨èªãã¨ããæãã§ãããçµæ§ä½ã¬ãã«ãªAPIãæã£ã¦ãã¦ããã£ãï¼ãã¼ã¢ã³åãç´ ç´ã«ã§ããªãã£ããã¨ä»¥å¤ï¼ã
- Rustã¨æ¯ã¹ããã¹ãã¬ã¹ããªã¼ã§ããæã£ãéãã«æ¸ãã ãã§ã¨ããããåãã¦ãããããã°ãããã
- è¦ãç®ã¯ããããã«é·ãã¦ããµãã§ããããã ãããæ¨ã¦ã¦å²ãåã£ã¦æ¸ããã¨è¨ããªãããªãã
- é å¸ããããã·ã³ã°ã«ãã¤ããªãä½ããã®ã¯ãã¯ããããä»åGoãé¸ãã çç±ãããã
ç´°ããã«ãã»ã«åãããããã
ã«ãã»ã«åã®åä½ãããã±ã¼ã¸ãããªãã®ãã¨ã«ããã¤ããã§ãããã¼ã«ã«å¤æ°ä»¥å¤ã®å¤æ°ãæ§é ä½ã®ãã£ã¼ã«ãããããã±ã¼ã¸å ã®ã©ããããåç §ã§ãã¦ãã¾ãã
ä»åã¯ããã¦èªè¦ããã®ã§ãããã¼ãã¯æ°åè¡åä½ã®ç´°ããæ½è±¡åãç©ã¿ä¸ãã¦ããã°ã©ã ãæ¸ãããã§ãããã¨ãã°Rubyã ã¨ãã¤ã³ã¹ã¿ã³ã¹å¤æ°ã¯åºæ¬çã«classï½endã®ä¸ã§ããã¢ã¯ã»ã¹ã§ãã¾ãããããã«ãããåä¸ãã¡ã¤ã«å ã§ãç´°ããã«ãã»ã«åãã§ãã¾ãã
åããã¨ãGoã§ããã«ã¯ãããã±ã¼ã¸ï¼ã¤ã¾ããã£ã¬ã¯ããªï¼ãåããªãã¨ãããªãã®ã§ãæ°åè¡ã®ãã¡ã¤ã«ãä¸ã¤ã ããããã£ã¬ã¯ããªã大éã«ä½ããã¡ã«ãªãããã§ãããããªã®æããã«ãããããªãããGoçã«æ¨å¥¨ããã¦ããªãããã§ãã
å¥æ¡ã¨ãã¦ããã¹ã¦ã®structãinterfaceã«ãã£ã¹ããã¦æ±ãæãæããã¾ããããããã¯æããã«é¢åãããããï¼ããã¾ã¾ï¼ã
æ
£ãã®åé¡ãããã¨æãã¾ãããåä¸ããã±ã¼ã¸å
ã§ããã¡ã¤ã«åä½ãªã©ã§æ軽ã«ã«ãã»ã«åãããããã®ç¹ã¯extern宣è¨ãããããã¡ã¤ã«ã#include
ããCè¨èªã®ã»ãããã·ã¨ããæã£ãã
goroutineããããã
ããããããªãã§ããï¼ wsl2-ssh-agentã§ã¯ãè¤æ°ã®sshã¯ã©ã¤ã¢ã³ãããã®ãªã¯ã¨ã¹ããåãã¦ãããããã·ã¼ã±ã³ã·ã£ã«ã«å¦çãããµã¼ããæ¸ãå¿ è¦ããã£ãã®ã§ãããè¨è¨ã«æ°æé以ä¸ãããã¾ããã
ã¨ããããåããã ããªã10åãããã§ã§ãããã§ãããéã«ç«ã¡ä¸ããgoroutineããã¹ã¦ãã¡ãã¨çµäºãããã®ããã¡ããã¡ãããã©ããéã«ãã£ã³ãã«ãã¯ãã¼ãºããã¨ãããã«æ¸ãè¾¼ãgoroutineãpanicããå¯è½æ§ãï¼ç¨ãªã¬ã¼ã¹ã³ã³ãã£ã·ã§ã³ã¨ãã¦ï¼è¦ã¤ãã£ããããã®ã§ãçµäºãããã¹ãé åºããã¡ããã¡ãç¹ç´°ã§ããä»ããã°ãåãåããèªä¿¡ã¯ãªãã§ãã
Goã§ã¯contextã便å©ã¨ããåãèãã¦ã¾ããããIOå¾ ã¡ãcontextãåãåã£ã¦ãããªãã®ã§ãèå¿ãªã¨ããã§ä½¿ããªãå°è±¡ã§ããã
ãã®åé¡ã¯ä»è¨èªãªã楽ã¨ããããã§ããªãã§ãããä»åã®åé¡ã«éã£ã¦è¨ãã°ãã·ã³ã°ã«ã¹ã¬ããã§select(2)ã¿ãããªAPIã®ã»ãã楽ããã ã£ããªãã¨æãã¾ãããGoãæ¨ã¦ã¦Cè¨èªã§æ¸ãç´ããè¿·ã£ããããããgoroutineããã¹ã¦ãã¡ãã¨çµäºãããããªãã¦èããªãã»ãããããã§ãããã
ãã®ä»éãªææ³
- ããã¯è¨ã£ã¦ããã£ã±è¨è¿°ãåé·ãããã
if err != nil {}
ã¤ããããµã³ãã«ã³ã¼ãã®èªè§£ããã¤ããã - ãã£ã¡ãæ¸ããããããã«ã¯åãå¼±ãã®ã§ããªãã¨ãªãå²ã«åã£ã¦ãªãæ°åãnil unsafeã¨ãã¯å¥ã«ãããã ãã©ãçµã¿è¾¼ã¿ã§optional intããã欲ããã
- ãã£ã¡ãæ¸ããããããã«ã¯ã¨ã©ã¼ã®æ±ããå¾®å¦ï¼ ã¨ã©ã¼ã®ã¨ããã©ãã§ä½ãèµ·ãããææ¡ããã®ã«æéããããã¨æããã¨ãå¤ãã£ããã¹ã¿ãã¯ãã¬ã¼ã¹ã§è¦ããã
- ãã¹ããããããã
os.Exit(0)
ãå¼ã¶é¢æ°ã¯ã»ã¼ãã¹ãä¸è½ã¨ã *1 ãåçè¨èªã®ãã¹ã¿ããªãã£ã®é«ããããããã¦æããã
*1:os.Exit ãå¤æ°çµç±ã§å¼ã¶ããã«ãã¦ããã¦ãã¹ãæã«å·®ãæ¿ããã¿ãããªãã¯ããã¯ãããããã§ãããã³ã¼ãã«ã¨ã£ã¦å®å ¨ã«ç¡æå³ãªè¤éæ§ããã¹ãã®ããã ãã«å ¥ããã®ã¯ã¡ãã£ã¨ãªã¼ã
6x6ãªãã¼ã·ã®ç¥
絶対ã«åã¦ãªã6x6ãªãã¼ã·ãä½ãã¾ãããããªãã¯é»çªãAIãç½çªã§ãã
絶対ã«åã¦ãªã6x6ãªãã¼ã·ãä½ãã¾ããï¼ ãã²ææ¦ãã¦ã¿ã¦ãã ããhttps://t.co/Ul5n3q9jMp
— Yusuke Endoh (@mametter) December 30, 2021
ããã¯ä½ï¼
6x6ã®ç¤é¢ã®ãªãã¼ã·ã¯å¾æå¿ å *1 ã§ãããã¨ãç¥ããã¦ãã¾ãã ãã®AIã¯ç½çªï¼å¾æï¼ã§å®ç§ã«ãã¬ã¤ãã¾ããã¤ã¾ãé»çªã®ããªãã¯çµ¶å¯¾ã«åã¦ã¾ãããç¡åæã楽ããã§ãã ããã
æè¡çãªè©±
ãã®AIã¯WebAssemblyã«ãªã£ã¦ããã®ã§ãå ¨é¨ããªãã®ãã©ã¦ã¶ã®ä¸ã§åãã¦ã¾ããçã®ãµã¼ãã¼ã¬ã¹ã§ãã
AIã®ã½ã¼ã¹ã³ã¼ãã¯Rustã§æ¸ãã¾ãããããã¨å å®ãªã²ã¼ã æ¨æ¢ç´¢ã«ãªã£ã¦ã¾ããUIã¯æ®éã«TypeScriptã¨three.jsã§å®è£ ãã¾ããã
ä½ã£ãé ã«èª¬æãã¾ãã
ç¤é¢ã®è¡¨ç¾
ãªã«ã¯ã¨ããããç¤é¢ã表ããã¼ã¿æ§é ãä½ãã¾ããï¼src/bitboard.rsï¼ã
ãã¡ã¤ã«åã®éããããããã¼ãã§ãã
Rustã®u64
ï¼64ãããæ´æ°ï¼ã2ã¤ä½¿ã£ã¦1ã¤ã®ç¤é¢ã表ç¾ãã¾ãï¼1ã¤ãé»ç³ã®ä½ç½®ããã1ã¤ãç½ç³ã®ä½ç½®ï¼ã
çæå¯è½æ°ã®ã«ã¦ã³ããªã©ãã¹ã¦ããããæ¼ç®ãé§ä½¿ãã¦ããã¾ãã ç³ãã²ã£ããè¿ãå¦çã¯æ¢ç´¢æ§è½ã«ç´çµããã®ã§ããã°ã£ã¦ã¾ãã 36ãã¹ãã¹ã¦ã«ç¹åããã³ã¼ãããã¯ãã§çæãã¦ã¾ãï¼src/bitboard/flip.rsï¼ã ãã ããæçµçã«WASMã«ããã®ã§ãã¢ã»ã³ããªãæ¸ããããªãã¨ã¯ãã¦ã¾ããã
ã¡ãªã¿ã«ããããã¼ããé¸ãã çç±ã¯ãããããªãã¨Rustã®ææ権ãåç¨ããããé¢åããããã ã£ãããã§ãã
ããããã¼ããªãu64
ã2ã¤ã ããªã®ã§ãéã«Copyãã¬ã¤ããå®è£
ãã¦ã大ä¸å¤«ã
çµç¤ã®ã¢ã«ã´ãªãºã
æåã«æ¸ããæ¢ç´¢ã¢ã«ã´ãªãºã ã¯ãåç´ãªãã¬ããã¯ã¹æ³ã§ãã ããã¯ã²ã¼ã çµç¤ï¼ç©ºããã¹ã11å以ä¸ï¼ã®æ¢ç´¢ã«ä½¿ã£ã¦ãã¾ãã
çµç¤ã®æ¢ç´¢ã¯ãåã£ãã¢ã«ã´ãªãºã ãããå®æ°ãªã¼ãã®æé©åãããå¹ãã¨ããã§ãã ãã¨ãã°ã空ããã¹ãæ¢ãããã«å ¨ãã¹ããã§ãã¯ããã¨é ãã§ãï¼çµç¤ã®å ´åãå¤ãã®ãã¹ã¯ãã§ã«ç³ãããã®ã§ç¡é§ï¼ã ããã§ãçµç¤ã®æ¢ç´¢ã«å ¥ãåã«ãã¹ã¦ã®ç©ºããã¹ã®ä½ç½®ãåæãã¦é£çµãªã¹ãã§ã¤ãªããå帰ã®ãã³ã«ãã®ãªã¹ãããªããããã«ãã¦ãã¾ãã
æ®å¿µãªãããRustã¯ãªã¹ãæ§é ã®æ±ãã極ãã¦ä¸å¾æãªè¨èªã§ã *2 ã
Rustã§ãªã¹ããä½ãã«ã¯ï¼åãã§ãã¯ãéãããã«ï¼ãªãã¡ã¬ã³ã¹ã«ã¦ã³ãã®ã»ã«ã使ãã®ãå®çªã®ããã§ãããä»åã¯ããã©ã¼ãã³ã¹ãéè¦ãªã®ã§unsafe
ã使ãã¾ããã
ããããã¨ãã¯unsafe
ã§è¯ãã¨ããç¥è¦ãããã£ã¦ããã®ã§ã
Programming Rust 以ä¸ã®è¨è¿°ãè¯ãã£ãããã³ã³ããã¯unsafeç¡ãã«å¹ççã«ã¯æ¸ããªãã®ã§unsafeã§è¯ãã ã¾ãããã®ä»¥ä¸ã®è¨è¿°ã¸ã®åçã«ãªã£ã¦ããã https://t.co/r5iunzkpWH pic.twitter.com/e2bk3R5IFE
— Yu SUGAWARA (@gusmachine) May 10, 2017
ä¸ç¤ã®ã¢ã«ã´ãªãºã
次ã«ãåç´ãªãã¬ããã¯ã¹æ³ã§æ·±ãèªããã¨ã¯ã§ããªãã®ã§ã空ããã¹ã12å以ä¸ããã¨ãã®ããã®ããå°ãè³¢ãã¢ã«ã´ãªãºã ãå®è£ ãã¾ããã ç½®æ表ä»ãMTD(f)ï¼è©ä¾¡é¢æ°ã«ããã ã¼ããªã¼ããªã³ã°ã¨ãããã¨ã¦ãæãªããã®æ¹æ³ã§ãï¼src/search/midgame.rsï¼ã
è©ä¾¡é¢æ°ã¯ãæåã§ä½ã£ãç¹å¾´éï¼ããããedge2xã®ãã¿ã¼ã³ã¨ãçæå¯è½æ°ï¼ãå ¥åã¨ããåã¡ãããè² ãããããäºæ¸¬ãã¾ãã ããã®å¦ç¿ã®ããã«ãä¸ç¤ã®ç¤é¢ãæ°åä¸ã»ã©ã©ã³ãã çæããããããã«å¯¾ãã¦çµç¤æ¢ç´¢ã®ã¢ã«ã´ãªãºã ã使ã£ã¦å®éã®åæãå¤å®ãã¾ããã ããã¦å®éã®åæãæ師ãã¼ã¿ã¨ãã¦ç¼ããªã¾ãæ³ã¨ææ¥éä¸æ³ãé©å½ã«ä½¿ã£ã¦éã¿ã決ãã¾ããï¼src/learn.rsï¼ã å¦ç¿ããéã¿ã¯æµ®åå°æ°ç¹æ°ã3000åã¡ãã£ã¨ãªã®ã§ãRustã®é åã¨ãã¦ã³ã¼ãã«ç´æ¥åãè¾¼ãã§ããã¾ãï¼data/weight.rsï¼ã
ãã¨ãããããã¼ãã®edge2xãã¿ã¼ã³ããé«éã«ä¿æ°ãç®åºããããã«ãå®å ¨ããã·ã¥ãç¨æãã¾ããã
è£è¶³ ãã®ãã¥ã¼ãªã¹ãã£ãã¯ãªè©ä¾¡é¢æ°ã¯ããã¾ã§ã ã¼ããªã¼ããªã³ã°ï¼è¯ããããªæããå ã«èª¿ã¹ããã¨ã§æåããå¢ãããã¯ããã¯ï¼ã®ããã«ä½¿ã£ã¦ããã ãã§ããã¡ã¤ã³ã®æ¢ç´¢ã§ã¯ã空ããã¹ã11åã®ã¨ããã¾ã§èªãã ãçµç¤æ¢ç´¢ã¢ã«ã´ãªãºã èªä½ãè©ä¾¡é¢æ°ã¨ãã¦ä½¿ãã¾ãããªã®ã§ãå ¨ä½ã¨ãã¦ã¯è¿ä¼¼è§£æ³ã§ã¯ãªãå®å ¨æ¢ç´¢ã«ãªãã¾ãã
åºç¤ã®ã¢ã«ã´ãªãºã
6x6ã®ãªãã¼ã·ã¯1993å¹´ã«å¾æå¿ åã§ãããã¨ã示ãããããã§ãã å½æã®ã¯ã¼ã¯ã¹ãã¼ã·ã§ã³ã§æ°é±éãããããã¦æ¢ç´¢ãããããã§ããããããªè¨ç®ãç¾ä»£ã§ã¯ä¸ç¬â¦â¦ãã¨æã£ãã®ã§ãããããã¾ã§ã§ä½ã£ãã¢ã«ã´ãªãºã ã§åæç¤é¢ããã®æ¢ç´¢ãããã¨ã1åå¼·ãããã¾ããããã£ã¼ãã©ã¼ãã³ã°ã§è©ä¾¡é¢æ°ä½ã£ã¦ã ã¼ããªã¼ããªã³ã°ããã¨ãã£ã¨éããªãã®ããªãï¼
ããã§ãªã¢ã«ã¿ã¤ã ã«æ¢ç´¢ããã®ã¯å³ããã®ã§ãåºç¤ã®16æããããããè¨ç®ãã¦ãã¾ããã¨ã«ãã¾ããã é»ãä»»æã®æãé¸ã¶ã®ã«å¯¾ããç½ã®æã¯1ã¤ã ãè¦ããã°ããã®ã§ãæ·±ã8ã®ããªã¼ãä½ãã¾ãã ç½ã¯æåæï¼æã大ããç³å·®ã§åã¤æï¼ã®ãã¡ãé»ã®çæå¯è½æ°ãå°ãããªãæãé¸ã¶ããã«ãããã¨ã§ããªãã¹ãè¦ããæ°ãæ¸ããã¾ããã çµæçã«ãããã10ä¸ç¤é¢ç¨åº¦ãè¦ãããã¨ã«ãªãã¾ããã
ããªã¼é¨åã¯ç°¡æ½ãã¼ã¿æ§é ã使ã£ãLOUDSã¨ãã表ç¾ã§ã¨ã³ã³ã¼ãããããã700ãããã¤ãã¨ãªã£ã¦ãã¾ã *3 ã
ãããªã«å¤§ãããªãã®ã§ãinclude_bytes!
ãã¯ãã§ãã¤ããªãã¼ã¿ãç´æ¥å®è¡ãã¡ã¤ã«ã«åãè¾¼ã¿ã¾ããã
ããã§AIã¯å®æã§ãã
ãã©ã¦ã¶ã§åãã
ããã¾ã§ã¯ãLinuxã§ã®ãã¤ãã£ãå®è¡ãã¡ã¤ã«ã¨ãã¦ä½ã£ã¦ã¾ããã ä»åã¯æ¢ç´¢ããã©ã¦ã¶ã§åããç®æ¨ã ã£ãã®ã§ãwasm-bindgenã§ãã©ã¦ã¶åãã®APIãç¨æãï¼src/api.rsï¼ãwasm-packã§WebAssemblyï¼ä»¥ä¸wasmï¼ã«ãã¾ããã emscriptenã«æ¯ã¹ãã¨ã³ã£ããããã»ã©ç°¡åã«wasmãã§ããã®ã§ã³ã£ãããã¾ããã
ãã ãåããã¦è¦ãã¨panicã§è½ã¡ã¾ããã
ããã£ã±ãwasmçæã¯å®æ度ãããªã«é«ããªãã®ããªã¼ããªã©ã¨ä»äººã®ããã«ãã¤ã¤ãä½ãèµ·ãã¦ããã調ã¹ã¦ã¿ãã¨ãusize
ã§ãªã¼ãã¼ããã¼ãçºçãã¦ã¾ããã
試ãã¦ããã¤ãã£ããã«ãã¯64ããããªã®ã§ãªã¼ãã¼ããã¼ããªãã®ã§ãããwasmã¯32ããããªã®ã§ãªã¼ãã¼ããã¼ãèµ·ããã
è¦ããã«å®å
¨ã«èªåã®ããã§ãããå®æ度é«ããªãã
ç´ãããç¡äºã«wasmãWeb workerããåãã¾ããã ãªããpanicã¯èª¿ã¹å§ãã¦ããæ°ååã§ç´ããã®ã«å¯¾ããwasm+Web workerã®webpackã®è¨å®ã«æ°æéã»ã©æ¶è²»ãã¾ãããwebpack許ããªãã
UIé¨å
ããã¾ã§Rustã§éçºãã¦ããã®ã§ãUIãyewã§ï¼ ãªã©ã¨èããªãããªãã£ãã®ã§ããããã®æç¹ã§Rustã¸ã®ãã¤ããæºã¾ãããã¦ããã®ã§TypeScriptã§æ¸ãã¾ããã ããã¼ãã¡ãã£ã¨mapãããã ããªã®ã«iterã ã®collectã ã®æ¸ããªãã¨ãããªãã¨ããéãªã³ã¼ãæ¸ãã¨unwrapã ããã«ãªããâ¦â¦ã
é話ä¼é¡ã
ãã£ãããUIãä½ããããªã£ãã®ã§ãthree.jsã使ããã¨ã«ãã¾ããã æåã¯Reactã§å®è£ ãããã¨ãã¾ããããthree.jsãç¶æ ã®ããã¾ãã§ç¸æ§ææªã ã£ã *4 ã®ã§ãç´ ã§æ¸ãã¾ããã
éæ
å®å ¨è§£æããã¦ããã²ã¼ã ã¯ãã©ããã£ã¦ãåã¦ãªãã¨ãããå®éã«ä½é¨ãããã§ãããã 6x6ãªãã¼ã·ã®ãã¼ãã§ã¯ããã¬ã¤ã®æ£èã¯çºè¦è ã®Joel Feinsteinãæ¸ãããã¥ã¼ã¹ã¬ã¿ã¼ãå§ããããããªã¨ããã§è¦ããã¾ãããã¤ã³ã¿ã©ã¯ãã£ãã«ã§ãããã®ã¯è¦ã¤ãããªãã£ãã®ã§ä½ãã¾ããã
ãã¨ãwasmã§éãã§ã¿ããã£ãã®ãåæ©ã§ãã 6x6ãªãã¼ã·ã¯å ¨ç¤é¢ããã¼ã¿ãã¼ã¹ã«ããã®ã¯æããã«ç¡çãªã®ã§ããã©ã¦ã¶ã§ç¾å®çã«åãããé度ã¨ãã¤ããªãµã¤ãºãå®ç¾ããã«ã¯wasmãããããªã¨ã ã¯ããWebã¢ããªã®ããã³ãã¨ã³ããå ¨é¨wasmã§åãä¸çã«ãªãã¨ãããªãã
ã¾ã¨ã
6x6ã®ãªãã¼ã·ã¯ãã£ã±ãåã¦ã¾ããã§ããã
*1:å¾æãæ£ããæãé¸ã³ç¶ããããå æã絶対ã«åã¦ãªããã¨ã
*2:Rustã¨ãªã¹ãã§æ¤ç´¢ããã¨ããªã¹ãæ§é ã¯å®ç¨ããã°ã©ã ã§ã¯ã»ã¨ãã©ç»å ´ããªããããããã ãã¿ãããªä¸»å¼µãå¤æ°è¦ããã¾ãããã£ã±ãã¶ã©ãï¼
*3:æ£ç¢ºã«è¨ãã¨ãããªã¼æ§é ã®ãã¼ã¿ã¯80ãããã¤ãç¨åº¦ã§ã大åã¯é»ã®æã®ä¾¡å¤ï¼æçµçãªç³å·®ï¼ã¨ç½ãæã¤ã¹ãä½ç½®ã®ãã¼ã¿ã§ãã
*4:æåã¯@react-three/fiberã試ãã¾ããããã¾ã¨ãã«ããã©ã¼ãã³ã¹ãåºãããã«ã¯ã¢ãã¡ã¼ã·ã§ã³ç¶æ ãªã©ãReactããå¥ç®¡çãããããªãããã§ãReactã使ãæå³ãèããã ã£ãã