mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
![]() Previously, the right hand side was always evaluated before the left hand side for constant assignments. For the following: ```ruby lhs::C = rhs ``` rhs was evaluated before lhs, which is inconsistant with attribute assignment (lhs.m = rhs), and apparently also does not conform to JIS 3017:2013 11.4.2.2.3. Fix this by changing evaluation order. Previously, the above compiled to: ``` 0000 putself ( 1)[Li] 0001 opt_send_without_block <calldata!mid:rhs, argc:0, FCALL|VCALL|ARGS_SIMPLE> 0003 dup 0004 putself 0005 opt_send_without_block <calldata!mid:lhs, argc:0, FCALL|VCALL|ARGS_SIMPLE> 0007 setconstant :C 0009 leave ``` After this change: ``` 0000 putself ( 1)[Li] 0001 opt_send_without_block <calldata!mid:lhs, argc:0, FCALL|VCALL|ARGS_SIMPLE> 0003 putself 0004 opt_send_without_block <calldata!mid:rhs, argc:0, FCALL|VCALL|ARGS_SIMPLE> 0006 swap 0007 topn 1 0009 swap 0010 setconstant :C 0012 leave ``` Note that if expr is not a module/class, then a TypeError is not raised until after the evaluation of rhs. This is because that error is raised by setconstant. If we wanted to raise TypeError before evaluation of rhs, we would have to add a VM instruction for calling vm_check_if_namespace. Changing assignment order for single assignments caused problems in the multiple assignment code, revealing that the issue also affected multiple assignment. Fix the multiple assignment code so left-to-right evaluation also works for constant assignments. Do some refactoring of the multiple assignment code to reduce duplication after adding support for constants. Rename struct masgn_attrasgn to masgn_lhs_node, since it now handles both constants and attributes. Add add_masgn_lhs_node static function for adding data for lhs attribute and constant setting. Fixes [Bug #15928] |
||
---|---|---|
.. | ||
fixtures | ||
predefined | ||
regexp | ||
shared | ||
alias_spec.rb | ||
and_spec.rb | ||
array_spec.rb | ||
BEGIN_spec.rb | ||
block_spec.rb | ||
break_spec.rb | ||
case_spec.rb | ||
class_spec.rb | ||
class_variable_spec.rb | ||
comment_spec.rb | ||
constants_spec.rb | ||
def_spec.rb | ||
defined_spec.rb | ||
delegation_spec.rb | ||
encoding_spec.rb | ||
END_spec.rb | ||
ensure_spec.rb | ||
execution_spec.rb | ||
file_spec.rb | ||
for_spec.rb | ||
hash_spec.rb | ||
heredoc_spec.rb | ||
if_spec.rb | ||
lambda_spec.rb | ||
line_spec.rb | ||
loop_spec.rb | ||
magic_comment_spec.rb | ||
match_spec.rb | ||
metaclass_spec.rb | ||
method_spec.rb | ||
module_spec.rb | ||
next_spec.rb | ||
not_spec.rb | ||
numbered_parameters_spec.rb | ||
numbers_spec.rb | ||
optional_assignments_spec.rb | ||
or_spec.rb | ||
order_spec.rb | ||
pattern_matching_spec.rb | ||
precedence_spec.rb | ||
predefined_spec.rb | ||
private_spec.rb | ||
proc_spec.rb | ||
range_spec.rb | ||
README | ||
redo_spec.rb | ||
regexp_spec.rb | ||
rescue_spec.rb | ||
retry_spec.rb | ||
return_spec.rb | ||
safe_navigator_spec.rb | ||
safe_spec.rb | ||
send_spec.rb | ||
singleton_class_spec.rb | ||
source_encoding_spec.rb | ||
string_spec.rb | ||
super_spec.rb | ||
symbol_spec.rb | ||
throw_spec.rb | ||
undef_spec.rb | ||
unless_spec.rb | ||
until_spec.rb | ||
variables_spec.rb | ||
while_spec.rb | ||
yield_spec.rb |
There are numerous possible way of categorizing the entities and concepts that make up a programming language. Ruby has a fairly large number of reserved words. These words significantly describe major elements of the language, including flow control constructs like 'for' and 'while', conditional execution like 'if' and 'unless', exceptional execution control like 'rescue', etc. There are also literals for the basic "types" like String, Regexp, Array and Integer. Behavioral specifications describe the behavior of concrete entities. Rather than using concepts of computation to organize these spec files, we use entities of the Ruby language. Consider looking at any syntactic element of a Ruby program. With (almost) no ambiguity, one can identify it as a literal, reserved word, variable, etc. There is a spec file that corresponds to each literal construct and most reserved words, with the exceptions noted below. There are also several files that are more difficult to classify: all predefined variables, constants, and objects (predefined_spec.rb), the precedence of all operators (precedence_spec.rb), the behavior of assignment to variables (variables_spec.rb), the behavior of subprocess execution (execution_spec.rb), the behavior of the raise method as it impacts the execution of a Ruby program (raise_spec.rb), and the block entities like 'begin', 'do', ' { ... }' (block_spec.rb). Several reserved words and other entities are combined with the primary reserved word or entity to which they are related: false, true, nil, self predefined_spec.rb in for_spec.rb then, elsif if_spec.rb when case_spec.rb catch throw_spec.rb