Reputation: 4241
In CoffeeScript, let's say I've got the following:
class Greeter
message: ->
greeting = switch @gender
when 'male' then 'Sir'
when 'female' then 'Madame'
else 'Unknown'
"Hello #{greeting}!"
greeter = new Greeter
greeter.gender = 'Male'
alert greeter.message()
This currently alerts Hello Unknown!
when I want it to output Hello Sir!
.
How do I make it so that the Greeter
class will lowercase the @gender
instance variable so that the correct output is achieved? I don't want to just lowercase it in the message
method, but rather, all throughout an Instance of the Class. This is so that it works in other methods too.
I think I'm missing something very basic but I just can't seem to wrap my head around it.
NOTE: To those saying I got the capitalization wrong for "Male". Yes, I purposely did that. I'd like the class to automatically lowercase gender
in all cases, before using it. So the user can get the capitalization wrong and it still works.
The reason is that I'd eventually like to extrapolate this to other situations, rather than just those dealing with case-insensitivity issues.
Some people have mentioned JavaScript Getters and Setters, which are relatively new and therefore not supported in all major browsers. I'll take a look at those. I'm somewhat familiar with them through Ruby.
Upvotes: 1
Views: 319
Reputation: 46609
coffee>
class Greeter
message: =>
greeting =
if /^male/i.test(@gender) then 'Sir'
else if /^female/i.test(@gender) then 'Madame'
else 'Unknown'
"Hello #{greeting}!"
greeter = new Greeter
greeter.gender = 'Male'
greeter.message()
'Hello Sir!'
coffee> greeter.gender = 'female'
'female'
coffee> greeter.message()
'Hello Madame!'
coffee> greeter.gender = 'smizmar'
'smizmar'
coffee> greeter.message()
'Hello Unknown!'
coffee>
So that's the simple way to do it, but it doesn't change the value stored. To do that, you'll need to use Object.defineProperty (SO answer about it):
Function::property = (prop, desc) ->
Object.defineProperty @prototype, prop, desc
class Greeter
constructor: () ->
@property 'gender',
get: -> "#{@ciGender}"
set: (v) -> @ciGender = v.toLowerCase()
message: ->
greeting = switch @ciGender
when 'male' then 'Sir'
when 'female' then 'Madame'
else 'Unknown'
"Hello #{greeting}!"
Upvotes: 0
Reputation: 52040
Male
is not male
. Try normalize your string as lower case:
message: ->
greeting = switch @gender.toLowerCase()
when 'male' then 'Sir'
when 'female' then 'Madame'
else 'Unknown'
If necessary, you might want to encapsulate the call to lowercase in some property getter: https://stackoverflow.com/a/11592890/2363712 Something like that:
class Greeter
constructor: ->
Object.defineProperty @, 'gender',
get: ->
return @_gender
set: (value) ->
@_gender = value.toLowerCase()
message: ->
greeting = switch @gender
when 'male' then 'Sir'
when 'female' then 'Madame'
else 'Unknown'
"Hello #{greeting}!"
For this to work, your run-time environment must support Object.defineProperty
See that table for a quick lookup of supported browsers.
Upvotes: 2