Ką reiškia žemėlapis ( pavadinimas) Ruby?

RailsCast rado šį kodą:

 def tag_names @tag_names || tags.map( ') end 

Ką reiškia (> map(> ?

456
01 авг. nustatė collimarco 01 rug . 2009-08-01 20:35 '09 ne 20:35 2009-08-01 20:35
@ 14 atsakymų

Ši tags.map( ') santrumpa tags.map( ')

Jei „ foo yra objektas, turintis „metodas“, galite perduoti jį tokiam metodui kaip > , kuris paskambins „ foo.to_proc ir naudos jį kaip metodo bloką.

Symbol#to_proc iš pradžių buvo pridėtas „ActiveSupport“, bet buvo integruotas į „Ruby“ 1.8.7. Tai yra jos įgyvendinimas:

 class Symbol def to_proc Proc.new do |obj, *args| obj.send self, *args end end end 
478
01 авг. atsakymą pateikė josh lee 01 rug. 2009-08-01 20:50 '09 ne 20:50 2009-08-01 20:50

Dar vienas didelis daugeliui nežinomas spartusis klavišas

 array.each(> 

trumpas

 array.each { |element| foo(element) } 

Skambinimo method(:foo) , mes paėmėme Method objektą iš self , kuris reiškia jo metodą foo , ir naudojo > nurodydamas, kad jis turi to_proc metodą , kuris konvertuoja jį į Proc .

Tai labai naudinga, kai norite atlikti taško stilių. Pavyzdys yra patikrinti, ar matricoje yra bet kokia eilutė, lygi eilutę "foo" . Yra įprastas būdas:

 ["bar", "baz", "foo"].any? { |str| str == "foo" } 

Ir yra nesąžiningas kelias:

 ["bar", "baz", "foo"].any?(> 

Pageidautinas metodas turėtų būti labiausiai skaitomas.

161
08 марта '12 в 21:07 2012-03-08 21:07 atsakymą pateikė „ Gerry “ kovo 8 d. 12 d. 21:07 2012-03-08 21:07

Tai atitinka

 def tag_names @tag_names || tags.map { |tag| tag.name }.join(' ') end 
71
01 авг. atsakymą pateikė Sophie Alpert 01 rug. 2009-08-01 20:39 '09 ne 20:39 2009-08-01 20:39

Mes taip pat parodome, kad amperų magija #to_proc gali dirbti su bet kuria klase, o ne tik su simboliu. Daugelis rubistų pageidauja apibrėžti #to_proc „Array“ klasėje:

 class Array def to_proc proc { |receiver| receiver.send *self } end end # And then... [ 'Hello', 'Goodbye' ].map  :+, ' world!' ] #=> ["Hello world!", "Goodbye world!"] 

„Ampersand > works“ siunčia žinutę į to_proc , kuri pirmiau minėtame kode yra„ Array “klasė. Ir kadangi aš apibrėžiau #to_proc metodą masyve, eilutė atrodys taip:

 [ 'Hello', 'Goodbye' ].map { |receiver| receiver.send( :+, ' world!' ) } 
39
20 нояб. Atsakymą pateikė Boris Stitnicky 20 nov. 2012-11-20 15:38 '12, 15:38 PM 2012-11-20 15:38

Tai santrumpos tags.map { |tag| tag.name }.join(' ') tags.map { |tag| tag.name }.join(' ')

35
01 авг. atsakymas suteikiamas Oliveriui N. 01 rug. 2009-08-01 20:37 '09 ne 20:37 2009-08-01 20:37
 tags.map(> 

Tas pats kaip ir

 tags.map{|tag| tag.name} 

> paprasčiausiai naudojamas kaip vadinamojo metodo pavadinimas.

27
01 нояб. atsakymas pateikiamas Albert.Qing 01 lapkričio. 2016-11-01 06:23 '16 at 6:23 am 2016-11-01 06:23

Josh Lee atsakymas beveik teisingas, išskyrus tai, kad lygiavertis Ruby kodas turėtų būti toks.

 class Symbol def to_proc Proc.new do |receiver| receiver.send self end end end 

ne

 class Symbol def to_proc Proc.new do |obj, *args| obj.send self, *args end end end 

Naudojant šį kodą, kai print [[1,'a'],[2,'b'],[3,'c']].map(> vykdomas print [[1,'a'],[2,'b'],[3,'c']].map(> , Ruby suskaido pirmąjį įvestį [1,'a'] į 1 ir „a“, kad suteiktų obj 1 ir args* ' a ', kad sukeltų klaidą, nes Fixnum 1 objektas neturi savitos metodo (kuris yra: pirmasis).


Kai vykdoma [[1,'a'],[2,'b'],[3,'c']].map(> ;

  • :first tai yra simbolio objektas, todėl kai > nustatomas kaip žemėlapio metodas kaip parametras, vadinamas # to_proc simbolis.

  • žemėlapis siunčia žinutę skambinti: first.to_proc su [1,'a'] parametru, pavyzdžiui :first.to_proc.call([1,'a']) .

    Procedūra
  • Simbolių klasėje „to_proc“ siunčiamas pranešimas siunčiamas į masyvo objektą ( [1,'a'] ) su (: pirmuoju) parametru, pavyzdžiui, [1,'a'].send(:first) .

  • kartoja per likusius objekto elementus [[1,'a'],[2,'b'],[3,'c']] .

Tai yra tokia pati kaip ir išraiška [[1,'a'],[2,'b'],[3,'c']].map(|e| e.first) .

14
24 янв. Atsakymas pateikiamas prosseek 24 d 2014-01-24 00:08 '14 - 0:08 2014-01-24 00:08

Čia vyksta du dalykai, ir svarbu suprasti abu dalykus.

Kaip aprašyta kituose atsakymuose, Symbol#to_proc metodas.

Bet to_proc priežastis yra vadinama simboliu, nes jis perduodamas map kaip blokinis argumentas. Dėl argumento įtraukimo į metodinį skambutį jis perduoda šį kelią. Tai pasakytina apie bet kurį Ruby metodą, o ne tik map su simboliais.

 def some_method(*args,  puts "args: #{args.inspect}" puts "block: #{block.inspect}" end some_method(:whatever) # args: [:whatever] # block: nil some_method( # args: [] # block: #<Proc:0x007fd23d010da8> some_method( # TypeError: wrong argument type String (expected Proc) # (String doesn't respond to #to_proc) 

Symbol konvertuojamas į Proc nes jis perduodamas kaip blokas. Tai galime parodyti bandydami perkelti proc į .map be ir:

 arr = %w(apple banana) reverse_upcase = proc { |i| i.reverse.upcase } reverse_upcase.is_a?(Proc) => true arr.map(reverse_upcase) # ArgumentError: wrong number of arguments (1 for 0) # (map expects 0 positional arguments and one block argument) arr.map( => ["ELPPA", "ANANAB"] 

Nors tai nereikia konvertuoti, metodas nežino, kaip jį naudoti, nes jis tikisi blokinio argumento. Perdavimas > .map numatomą bloką.

8
09 апр. atsakymas pateikiamas devpuppy 09 apr. 2016-04-09 04:43 '16 at 4:43 2016-04-09 04:43

( name) yra sutrumpintas ( name.to_proc), jis yra panašus į tags.map{ |t| t.name }.join(' ') tags.map{ |t| t.name }.join(' ')

to_proc faktiškai įgyvendinamas C

5
25 авг. atsakymą pateikė tessie 25 rug . 2016-08-25 08:50 '16 at 8:50 2016-08-25 08:50

Nors mes jau turime puikius atsakymus, žiūrėdami į naujoką, norėčiau pridėti papildomos informacijos:

Ką reiškia žemėlapis ( pavadinimas) Ruby?

Tai reiškia, kad jūs rodote kitą metodą kaip parametrą rodymo funkcijai. (Tiesą sakant, jūs perduodate simbolį, kuris yra konvertuojamas į proc. Bet tai nėra labai svarbu šiuo konkrečiu atveju).

Svarbu tai, kad turite pavadintą name kuris bus naudojamas kaip žemėlapio metodo argumentas vietoj tradicinio block stiliaus.

2
08 дек. Atsakymą pateikė Jonathan Duarte 08 dec. 2017-12-08 18:23 '17 18:23 PM 2017-12-08 18:23

tai reiškia

 array.each(> 
1
20 дек. Atsakymas suteikiamas 20 min. 2016-12-20 15:25 '16 at 15:25 pm 2016-12-20 15:25

Čia :name yra simbolis, rodantis žymos objekto name metodą. Kai mes perkeliame > į map , jis bus laikomas name proc. Trumpai tariant, tags.map(> veikia kaip:

 tags.map do |tag| tag.name end 
1
30 июня '16 в 9:30 2016-06-30 09:30 atsakymas, kurį pateikė „ timlentse “ birželio 30 d. 16 val. 9:30 2016-06-30 09:30

žemėlapis ( name) užima suskirstytą objektą (žymas jūsų atveju) ir vykdo kiekvieno elemento / žymens pavadinimo metodą, rodydamas kiekvieną metodo grąžinimo vertę.

Tai trumpas

 array.map { |element| element.name } 

kuris grąžina elementų pavadinimų masyvą (žymes)

0
01 сент. Atsakymas duotas Sunda 01 Sep. 2018-09-01 07:48 '18 at 7:48 2018-09-01 07:48

Tai yra tokia pati kaip toliau:

 def tag_names if @tag_names @tag_names else tags.map{ |t| t.name }.join(' ') end 
0
27 июня '16 в 12:32 2016-06-27 12:32 atsakymą pateikė vartotojo3078630 birželio 27 d. 16 d. 12:32 2016-06-27 12:32