def track_for stat # This is a hash with 2 elements of proc { symbol: -> { send(stat) }, array: -> { send(stat[0], stat[1]) } }.freeze[stat.class.name.underscore.to_sym].call end 

freeze[stat.class.name.underscore.to_sym].call , I have no idea about this code. What is the function of the code inside [], and why use call method? Anyone who can help me? Much appreciate it.

3 Answers

Ruby Freeze method done following things on different objects, basically it's make object constant or immutable in ruby.

  1. String
str = "this is string" str.freeze str.replace("this is new string") #=> FrozenError (can't modify frozen String) or str[0] #=> 't' str[0] = 'X' #=> FrozenError (can't modify frozen String) 

But you can assign new string or change its reference. Once the reference change then it is not freeze (or constant) object.

str = "this is string" str.freeze str.frozen? #=> true str = "this is new string" str.frozen? #=> false 
  1. Array :-
arr = ['a', 'b', 'c'] arr.freeze arr << 'd' #=> FrozenError (can't modify frozen Array) arr[0] = 'd' #=> FrozenError (can't modify frozen Array) arr[1].replace('e') #=> ["a", "e", "c"] arr.frozen? #=> true 

arr array is frozen means you can’t change the array. But the strings inside the array aren’t frozen. If you do a replace operation on the string “one”, mischievously turning it into “e”, the new contents of the string are revealed when you reexamine the (still frozen!) array.

  1. Hash
hash = {a: '1', b: '2'} hash.freeze hash[:c] = '3' #=> FrozenError (can't modify frozen Hash) hash.replace({c: '3'}) #=> FrozenError (can't modify frozen Hash) hash.merge({c: '3'}) #=> return new hash {:a=>"1", :b=>"2", :c=>"3"} hash.merge!({c: '4'}) #=> FrozenError (can't modify frozen Hash) hash.frozen? #=> true hash = {:a=>"1", :b=>"2", :c=>"3"} hash.frozen? #=> false 

So we can't modify the hash content but we can refer it to new hash (just like array)

  • freeze - prevents modification to the Hash (returns the frozen object)
  • [] - accesses a value from the hash
  • stat.class.name.underscore.to_sym - I assume this returns a lowercase, snake case version of the given object's class name (underscore is not in the standard library, so I'm not completely sure)
  • call invokes the lambda associated with stat.class.name.underscore.to_sym key.

For instance, passing ['foo', 'bar'] as the argument to track_for would invoke the send(stat[0], stat[1]) lambda.

1

If we untangle the code it could be translated to:

def track_for stat case stat when Symbol send(stat) when Array send(stat[0], stat[1]) end end 

The hash in the code is used to choose the correct behavior according to the variable stat's class.

Actually, I don't see any virtue in the OP code above over the translated code - it is less readable and has no runtime benefits (as far as I can see)...

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy