What are advantages and disadvantages of dynamic type in Ruby?
Let's say I have a class called Tool:
class Tool
def initialize( name, weight )
@name = name
@weight = weight
end
attr_reader :name, :weight
attr_writer :name, :weight
def to_s
name + " " + weight
end
end
But this Tool
can be a person if I want to:
hammer = Tool.new( "Hammer", 14.5 )
pp = Tool.new( "first", "last" )
It's flexible because I can create one type and use for multiple purposes. However, if user accidentally makes a typo, it will definitely lead to wrong data type, how can we t开发者_Go百科rack the issue?
What are the advantages and disadvantages of this idea?Ruby is not loosely typed at all. Quite the contrary, it's very strongly typed. However it is also dynamically typed (as opposed to statically typed, such as C++ and Java). You should do some reading on the differences. PHP is an example of a loosely typed language.
And to answer your question, dynamically-typed languages such as Ruby and Python are very difficult to write with any amount of complexity without employing Test-Driven Development. That is, trying your hardest to write tests first to explain expectations and to define your classes and APIs such that people will know how to use them simply by using common sense. If you're really worried about clients passing invalid types to your methods, you can always type-check and throw exceptions if the types are incorrect. However, this is not typically done system-wide.
Static typing in most languages (well, Java & friends, I'm not considering the Haskell family here) makes programs verbose and over-constrains them, with little return at the design level. What's important when establishing a relation between two objects is what role they play and responsibilities they have, not what their type is, so static typing makes you think at the wrong level.
About robustness, just like null pointers, type errors typically cause catastrophic failure rather quickly, so they will never go undetected for long. So IMHO the class of errors prevented by static typing is not that interesting. On the other hand, anyone could write Tool.new( "Hammer", -42 )
which would be correct typewise, but the negative weight would probably lead to very strange behavior without failure. That's because that argument's role is a weight, which is never negative, and you cannot express that with a simple numeric type. So what's really needed at design time is not static types, but validations or contracts as in Eiffel.
Now, consider unanticipated software evolution: you want to integrate support for SI units. Do you see why the design decision of statically typing that parameter to number now looks like a premature one? In a dynamically typed system it's easier to craft a new object that knows arithmetic but takes unit conversions into account, and to use that directly in place of numbers in the existing code.
Of course, static types have documentation value, and dynamically typed languages require some discipline in that area, namely clear naming, good tests, good comments... but none of those are superfluous with static typing anyway.
I wouldn't describe that as loosely or dynamically typing - rather it's using one class for two distinct purposes. In general, you shouldn't create a class that general to store completely disparate sets of data.
The disadvantages of your method are as you mentioned - user confusion and potential bad data. You should probably create a second class, Person
, to handle your objects that are people. It eliminates confusion and has zero potential for users to make a typo and create the wrong data type.
[edit]
And to prevent users from entering bad data, you could modify your weight=
method that is created by your attr_writer like so:
def weight= value
@weight = value.to_i # only store integers
end
Or check that the string entered is actually a number and raise an exception if not.
精彩评论