Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
This is a patch to Ruby 2.5.0 to enable es6 like hash literals - instructions in the comments
From a034498e36c02715b9201646d4ce1ddcddf118c3 Mon Sep 17 00:00:00 2001
From: Shugo Maeda <shugo@ruby-lang.org>
Date: Wed, 29 Apr 2015 09:14:15 +0900
Subject: [PATCH] support ES6-like hash literals.
---
parse.y | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 72 insertions(+), 17 deletions(-)
diff --git a/parse.y b/parse.y
index 7e85d70..dd03433 100644
--- a/parse.y
+++ b/parse.y
@@ -477,6 +477,10 @@ static int reg_fragment_check_gen(struct parser_params*, VALUE, int);
static NODE *reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *match);
#define reg_named_capture_assign(regexp,match) reg_named_capture_assign_gen(parser,(regexp),(match))
+static NODE *assoc_concat_gen(struct parser_params*,NODE*,NODE*);
+#define assoc_concat(assocs,tail) assoc_concat_gen(parser,(assocs),(tail))
+static ID var_to_assoc_key(ID);
+
#define get_id(id) (id)
#define get_value(val) (val)
#else
@@ -820,7 +824,7 @@ static void token_info_pop(struct parser_params*, const char *token);
%type <node> command_asgn mrhs mrhs_arg superclass block_call block_command
%type <node> f_block_optarg f_block_opt
%type <node> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
-%type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
+%type <node> assoc_list assoc_items assoc_item assocs assoc undef_list backref string_dvar for_var
%type <node> block_param opt_block_param block_param_def f_opt
%type <node> f_kwarg f_kw f_block_kwarg f_block_kw
%type <node> bv_decls opt_bv_decl bvar
@@ -5019,7 +5023,7 @@ singleton : var_ref
;
assoc_list : none
- | assocs trailer
+ | assoc_items trailer
{
/*%%%*/
$$ = $1;
@@ -5029,6 +5033,38 @@ assoc_list : none
}
;
+assoc_items : assoc_item
+ /*%c%*/
+ /*%c
+ {
+ $$ = rb_ary_new3(1, $1);
+ }
+ %*/
+ | assoc_items ',' assoc_item
+ {
+ /*%%%*/
+ $$ = assoc_concat($1, $3);
+ /*%
+ $$ = rb_ary_push($1, $3);
+ %*/
+ }
+ ;
+
+assoc_item : assoc
+ | user_variable
+ {
+ /*%%%*/
+ ID k = var_to_assoc_key($1);
+ NODE *key, *val;
+ key = NEW_LIT(ID2SYM(k));
+ if (!(val = gettable($1, &@$))) val = NEW_BEGIN(0);
+ $$ = list_append(NEW_LIST(key), val);
+ /*%
+ $$ = dispatch2(assoc_new, $1, id_is_var(get_id($1)) ? dispatch1(var_ref, $1) : dispatch1(vcall, $1));
+ %*/
+ }
+ ;
+
assocs : assoc
/*%c%*/
/*%c
@@ -5039,21 +5075,7 @@ assocs : assoc
| assocs ',' assoc
{
/*%%%*/
- NODE *assocs = $1;
- NODE *tail = $3;
- if (!assocs) {
- assocs = tail;
- }
- else if (tail) {
- if (assocs->nd_head &&
- !tail->nd_head && nd_type(tail->nd_next) == NODE_ARRAY &&
- nd_type(tail->nd_next->nd_head) == NODE_HASH) {
- /* DSTAR */
- tail = tail->nd_next->nd_head->nd_head;
- }
- assocs = list_concat(assocs, tail);
- }
- $$ = assocs;
+ $$ = assoc_concat($1, $3);
/*%
$$ = rb_ary_push($1, $3);
%*/
@@ -10439,6 +10461,39 @@ rb_parser_reg_compile(struct parser_params* parser, VALUE str, int options, VALU
return re;
}
+static NODE *
+assoc_concat_gen(struct parser_params *parser, NODE *assocs, NODE *tail)
+{
+ if (!assocs) {
+ assocs = tail;
+ }
+ else if (tail) {
+ if (assocs->nd_head &&
+ !tail->nd_head && nd_type(tail->nd_next) == NODE_ARRAY &&
+ nd_type(tail->nd_next->nd_head) == NODE_HASH) {
+ /* DSTAR */
+ tail = tail->nd_next->nd_head->nd_head;
+ }
+ assocs = list_concat(assocs, tail);
+ }
+ return assocs;
+}
+
+static ID var_to_assoc_key(ID var)
+{
+ switch (id_type(var)) {
+ case ID_LOCAL:
+ case ID_CONST:
+ return var;
+ default: {
+ const char *name = rb_id2name(var);
+ while (*name == '$' || *name == '@')
+ name++;
+ return rb_intern(name);
+ }
+ }
+}
+
NODE*
rb_parser_append_print(VALUE vparser, NODE *node)
{
--
1.9.1
@thechrisoshow

This comment has been minimized.

Copy link
Owner Author

thechrisoshow commented Feb 20, 2018

Ever wanted to have cool es6 style hash literals in Ruby?

e.g.

params = { name, email }
#=> { name: name, email: email }

The easiest way that I implemented this is by using rvm. Download this patch onto your computer and use rvm to install like this:

rvm install 2.5.0 -n imphash --patch imphash.patch

This will install a version of Ruby on your machine called ruby-2.5.0-imphash. You can select this if you want the fun es6 literals.

BIG NOTE
I did NOT create this patch. This was created by Shugo Maeda in 2015.
(Here's the original patch: https://bugs.ruby-lang.org/attachments/5194/0001-support-ES6-like-hash-literals.patch)

I only made one tiny change to make it work with the latest version of ruby.

Little note
Imphash is short for "implicit hash" - and cause I don't know what these are called I thought that could be good one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.