Last active
April 5, 2016 22:19
-
-
Save FlaviaFortes/f7060cc86c2e6f6a6d576e0ad09d712a to your computer and use it in GitHub Desktop.
Disruptivo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def pp2 (attrs) | |
puts attrs | |
puts attrs.class | |
end | |
irb(main):024:0> pp2([a: "a", b: 1]) | |
{:a=>"a", :b=>1} | |
Array | |
=> nil | |
irb(main):025:0> pp2({a: "a", b: 1}) | |
{:a=>"a", :b=>1} | |
Hash | |
=> nil | |
########## | |
irb(main):046:0> t = { "a": 1, "b": 2, "c": 3 } | |
=> {:a=>1, :b=>2, :c=>3} | |
irb(main):047:0> t.fetch("a") | |
KeyError: key not found: "a" | |
irb(main):052:0> t.fetch(:a) | |
=> 1 | |
irb(main):048:0> t.fetch(a) | |
NameError: undefined local variable or method `a' for main:Object |
No primeiro bloco ele realmente entende como um Hash dentro de um Array. Se colocarmos o método p
para printar, você percebe, ó:
Dado:
def pp2 (attrs)
puts attrs
p attrs
puts attrs.class
end
irb(main):061:0> pp2([a: "a", b: 1])
{:a=>"a", :b=>1}
[{:a=>"a", :b=>1}]
Array
=> nil
O método puts
remove os []
de um Array, exemplo:
irb(main):063:0> puts [1]
1
No segundo bloco:
O :
é como chamar o método to_sym
, então não funciona para qualquer valor:
irb(main):064:0> "a".to_sym
=> :a
irb(main):065:0> 1.to_sym
NoMethodError: undefined method `to_sym' for 1:Fixnum
O que torna as coisas engraçadas nesses casos:
irb(main):070:0> { 1=> "a", 2=> "b"}
=> {1=>"a", 2=>"b"}
irb(main):071:0> { 1: "a", 2: "b"}
SyntaxError: (irb):71: syntax error, unexpected ':'
Imaginei que poderia ser algo na linha do seguinte:
- o parser tenta ler o valor como
*args
, fazendo o splat para uma array ou um argumento opcional, com isso ele captura o primeiro caso; - em seguida ele tenta realizar o splat via
**kwargs
, entendendo que não há nenhum argumento exceto o hash final de chave-valor;
Faz algum sentido (ao menos na minha cabeça), imaginando uma implementação imperativa de como esse código é tratado. Infelizmente não consegui emular isso para um novo método. Talvez seja uma idiossincrasia do próprio puts
, talvez seja problema por ele ser implementado de forma nativa... talvez eu esteja completamente errado e por isso não consegui replicar ¯_(ツ)_/¯
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
No primeiro bloco o que eu imagino que esteja acontecendo é que implicitamente o parser do ruby está entendendo o seguinte:
Dado o uso da sintaxe "açucarada" de mapas com chaves feitas de símbolos. Por que ele printa diferente já é um mistério para mim... talvez alguma ambiguidade com a feature de keyword arguments.
Já o segundo bloco é um pouco mais esperado, embora não menos mágico:
é lido como
e
:"a"
é outra forma de definir o símbolo:a
. Por isso o primeirofetch
reclama e o segundo aceita de boas.EDIT: confirmando, o primeiro caso é realmente ambiguidade com keyword arguments.