0

In Ruby, I'm attempting to pass a boolean result to a method which accepts as a string as a parameter. This is as an experiment.

fileexists = File.file?("#{$fileLocation}")

puts File.file?("#{$fileLocation}")
puts fileexists
puts fileexists.to_s

This will result in:

true
true
true

Now if I attempt to call a method which accepts a string and pass this parameter in a number of ways.

slack(message: "#{fileexists}")

Results in the error message.

'message' value must be a String! Found TrueClass instead.

Which confuses me as I understand that Ruby evaluates anything within "" as a String. So placing a TrueClass object within a placeholder, should effectively cast this value to a string.

So let's try something slightly different:

slack(message: "#{fileexists.to_s}")

This results in the same error.

'message' value must be a String! Found TrueClass instead.

Now this is where things GET REALLY WEIRD!!

slack(message: "#{fileexists.to_s} ")
slack(message: "#{fileexists} ")

If I add a single bit of whitespace to the end of the string after the placeholder, it passes, and a slack message is sent my way, displaying 'true'.

I understand I may be asking for a bit of 'Crystal-ball' insight here as I don't have the implementation of the 'slack' method, and this may be a result of the way that's implemented.

Does Ruby check types of params as they're passed like this?

Is that a Ruby standard error message you might receive, or a custom error thrown by the slack() method?

Guy Joel McLean
  • 1,019
  • 4
  • 12
  • 34
  • What do you mean “ I don't have the implementation of the 'slack' method”?! I was always sure Ruby is kinda scripting language. You _always_ have a source code at fingers. – Aleksei Matiushkin Nov 16 '17 at 16:24
  • I'm using a tools called fastlane. I'll go do some digging in my library folder and see if i can find it. – Guy Joel McLean Nov 16 '17 at 16:26
  • So the source for this library is here: https://github.com/fastlane/fastlane/blob/master/fastlane/lib/fastlane/actions/slack.rb. – Guy Joel McLean Nov 16 '17 at 16:40
  • However i'm totally unable to find any thing described by 'def slack' that is the implementation of this method. – Guy Joel McLean Nov 16 '17 at 16:40
  • As a first guess, it looks like the slack method or whatever it passes its arguments on to, tries to deserialize the argument as JSON or YAML, and thinks it has the value `true` as opposed to the string `"true"` – Jörg W Mittag Nov 16 '17 at 16:51
  • try to call slack( fileexists ? 't' : 'f' ); – Akzhan Abdulin Nov 16 '17 at 16:55

3 Answers3

1

I understand I may be asking for a bit of 'Crystal-ball' insight here as I don't have the implementation of the 'slack' method, and this may be a result of the way that's implemented.

Sounds like youre using a lib (gem) which contains the methods slack, you can check the gem code location running gem which gem_name on your console.

Does Ruby check types of params as they're passed like this?

No

Is that a Ruby standard error message you might receive, or a custom error thrown by the slack() method?

Custom Error

As Jorg W Mittag stated this looks like a misimplementation of slack method when trying to deserialize, and then checking the types. You could fix the slack method on the gem by contributing to this gem, monkeypatch it or you can try to hack it the way it is... this last onde depends on how slack was implemented, maybe adding an extra pair of quotes, like "\"#{fileexists}\""

PS: You don't have to embbed the string inside another string if you're going to use it as it is, like fileexists = File.file? $fileLocation , this should work.

Alexandre Abreu
  • 1,382
  • 1
  • 13
  • 28
1

The dependency you are using, fastlane, auto-converts values that are passed into the actions (your call to slack).

The reason for this is that parameters in fastlane can also be specified via the commandline, so conversion is necessary. It converts your value of "true" to a boolean automatically because there is no Boolean class in ruby and the type of parameters is specified by giving it the name of a class, so it automatically converts "true" to a boolean. The offending line in the code is here.

As you can see in the code above, a workaround would be to do slack(message: "#{fileexists.to_s.capitalize}") or slack(message: fileexists ? "t" : "f"). Anything really as long as you avoid yes, YES, true, TRUE, no, NO, false, and FALSE

milch
  • 986
  • 8
  • 13
0

I'm only guessing here because we don't know what the method definition of slack is expecting an un-named String, but you're passing a hash.

slack(fileexists.to_s)
Daniel Westendorf
  • 3,375
  • 18
  • 23