a few thoughts for ruby...

Discussion in 'Ruby' started by Roger Pack, Apr 11, 2009.

  1. Roger Pack

    Roger Pack Guest

    Thought I'd pass these thoughts by the readers here before sending them
    to core. They're my current wish list :)

    1) add an Object#in? method to complement the existing Array#include?

    2) add some useful lists of exceptions, ex: IO.SELECT_EXCEPTIONS,
    IO.READ_EXCEPTIONS, so that you can rescue the wide gamut of them
    appropriately, should you desire to.

    3) provide an easier way to know which platform you're on than
    RUBY_PLATFORM =~ /mswin32|dgjpp|mingw/

    4) (this one's controversial) remove the extra # for code in strings
    (i.e. "string#{code}") -> "string{code}" less typing.

    5) add a BigDecimal(float) method.
    -> BigDecimal.new("%f" % float)

    6) add Dir.directory?
    -> File.directory?

    Feedback?
    Thanks!
    -=r
    --
    Posted via http://www.ruby-forum.com/.
     
    Roger Pack, Apr 11, 2009
    #1
    1. Advertising

  2. Roger Pack wrote:
    > Thought I'd pass these thoughts by the readers here before sending them
    > to core. They're my current wish list :)
    >
    > 1) add an Object#in? method to complement the existing Array#include?


    It's not really symmetrical. Array has an #include? method because it is
    a collection. Object has #in? because it is--what? A potential member of
    a collection?

    This would conflict with lots of potential other uses of #in? that have
    nothing to do with collections:

    Clutch#in?

    Doctor#in?

    Fix#in?

    (to start just with the 0-ary ones).

    > 2) add some useful lists of exceptions, ex: IO.SELECT_EXCEPTIONS,
    > IO.READ_EXCEPTIONS, so that you can rescue the wide gamut of them
    > appropriately, should you desire to.


    I've wanted that, and ended up with:

    ALL_NETWORK_ERRORS = [Errno::ECONNRESET, Errno::ECONNABORTED,
    Errno::ECONNREFUSED, Errno::EPIPE, IOError, Errno::ETIMEDOUT]

    ALL_NETWORK_ERRORS << Errno::EPROTO if defined?(Errno::EPROTO)
    ALL_NETWORK_ERRORS << Errno::ENETUNREACH if defined?(Errno::ENETUNREACH)

    Maybe a better way would be to include a module, AnyNetworkError, in
    each of these. Then you could

    rescue AnyNetworkError

    Like this:

    module E; end

    class E1 < StandardError; include E; end
    class E2 < StandardError; include E; end

    begin
    raise E1, "foo"
    rescue E => ex
    p ex
    end

    > 4) (this one's controversial) remove the extra # for code in strings
    > (i.e. "string#{code}") -> "string{code}" less typing.


    Would not like having to escape { in strings...

    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
     
    Joel VanderWerf, Apr 11, 2009
    #2
    1. Advertising

  3. Roger Pack

    Roger Pack Guest

    Thanks for the reply Joel.

    >> 1) add an Object#in? method to complement the existing Array#include?

    >
    > It's not really symmetrical. Array has an #include? method because it is
    > a collection. Object has #in? because it is--what? A potential member of
    > a collection?


    Yeah. I'm not saying it's symmetric as much as useful and
    intuitive--some of the big reasons I like Ruby :)
    Would #within? be better?

    > I've wanted that, and ended up with:
    >
    > ALL_NETWORK_ERRORS = [Errno::ECONNRESET, Errno::ECONNABORTED,
    > Errno::ECONNREFUSED, Errno::EPIPE, IOError, Errno::ETIMEDOUT]
    >
    > ALL_NETWORK_ERRORS << Errno::EPROTO if defined?(Errno::EPROTO)
    > ALL_NETWORK_ERRORS << Errno::ENETUNREACH if defined?(Errno::ENETUNREACH)


    Looks like it would indeed be useful--especially for cross platform
    where you 'wish you didnt have to know them all for every platform'
    (there really are a lot of them -- see
    http://betterlogic.com/roger/?p=1223 as an example).

    > Maybe a better way would be to include a module, AnyNetworkError, in
    > each of these. Then you could...


    Yeah, or have them all descend from a single ancestor. I would say just
    descend from SocketError except that SocketError is actually raised as
    an exception itself, every so often, so it has its own meaning
    currently...though I guess that doesn't stop it from being an ancestor.

    > module E; end

    ...
    > begin
    > raise E1, "foo"
    > rescue E => ex
    > p ex
    > end


    That's pretty elegant. With an array you can [non intuitively] also get
    by:

    > begin
    > raise SocketError "foo"
    > rescue *ALL_NETWORK_ERRORS => ex
    > p ex
    > end

    (I'm sure you knew that).


    >> 4) (this one's controversial) remove the extra # for code in strings
    >> (i.e. "string#{code}") -> "string{code}" less typing.

    >
    > Would not like having to escape { in strings...


    Ok. This next isn't meant as an attacking question but...do you use { in
    normal strings often? Granted probably more than #, but...?

    Thanks!
    -=r
    --
    Posted via http://www.ruby-forum.com/.
     
    Roger Pack, Apr 11, 2009
    #3
  4. Hi,

    At Sat, 11 Apr 2009 15:30:54 +0900,
    Roger Pack wrote in [ruby-talk:333612]:
    > Ok. This next isn't meant as an attacking question but...do you use { in
    > normal strings often? Granted probably more than #, but...?


    gettext, and printf in 1.9.

    printf "%{foo}\n", foo:1 #=> 1

    --
    Nobu Nakada
     
    Nobuyoshi Nakada, Apr 11, 2009
    #4
  5. On 11.04.2009 06:52, Roger Pack wrote:
    > Thought I'd pass these thoughts by the readers here before sending them
    > to core. They're my current wish list :)
    >
    > 1) add an Object#in? method to complement the existing Array#include?


    -0

    I don't see the benefit but I'm also not strongly against. I do see
    Joel's point about the reversion. Basically it is strange that every
    object should be able to answer a question that only the collection can
    answer. Plus, you can easily add it yourself if you need it.

    > 2) add some useful lists of exceptions, ex: IO.SELECT_EXCEPTIONS,
    > IO.READ_EXCEPTIONS, so that you can rescue the wide gamut of them
    > appropriately, should you desire to.


    A good idea. But I do not know how feasible this is. Not all OS have
    the same error reporting mechanisms and the mapping from OS errors to
    exception types would have to be maintained of all platforms.

    > 3) provide an easier way to know which platform you're on than
    > RUBY_PLATFORM =~ /mswin32|dgjpp|mingw/


    -1

    This would make a Ruby specific unification of operating systems
    necessary. This means that not only maintainers of automake need to
    keep track of operating systems but also maintainers of Ruby. Other
    difficulties are: how much level of detail do you provide? For one
    application it may be enough to know it's running on Linux, the other
    one needs to know the kernel version and a third one does not bother
    about versions but must know the distro. I see too much effort for too
    little benefit.

    > 4) (this one's controversial) remove the extra # for code in strings
    > (i.e. "string#{code}") -> "string{code}" less typing.


    -1

    Definitively a don't as the overhead of typing # isn't too big (plus, it
    is more easily spotted) and the potential for damage caused by this is
    large.

    > 5) add a BigDecimal(float) method.
    > -> BigDecimal.new("%f" % float)


    0

    Seems reasonable at first sight but the absence might have a reason.
    For example, by making the conversion to String explicit it is more
    obvious that float and BigDecimal are not really compatible.

    > 6) add Dir.directory?
    > -> File.directory?


    0

    Btw, there is also this nice idiom for those tests

    if test ?d, "some dir"

    Kind regards

    robert
     
    Robert Klemme, Apr 11, 2009
    #5
  6. Hi,

    At Sat, 11 Apr 2009 13:52:49 +0900,
    Roger Pack wrote in [ruby-talk:333607]:
    > 6) add Dir.directory?
    > -> File.directory?


    Dir.exist? exists in 1.9.

    --
    Nobu Nakada
     
    Nobuyoshi Nakada, Apr 11, 2009
    #6
  7. Roger Pack

    Roger Pack Guest

    >> 1) add an Object#in? method to complement the existing Array#include?
    >
    > -0
    >
    > I don't see the benefit but I'm also not strongly against. I do see
    > Joel's point about the reversion. Basically it is strange that every
    > object should be able to answer a question that only the collection can
    > answer. Plus, you can easily add it yourself if you need it.


    I kind of agree with Joel on this one, too.

    A few other observations:

    re: in?
    Currently with #select you've got one in Kernel [which is IO.select] but
    Arrays seem to have their own #select. So it is "conceivably possible"
    to have a "default #in?" and have it overridden by Clutch#in? or
    House#in? if desired.

    Another option would be included? -- might be more ruby-y :)

    >> 2) add some useful lists of exceptions, ex: IO.SELECT_EXCEPTIONS,
    >> IO.READ_EXCEPTIONS, so that you can rescue the wide gamut of them
    >> appropriately, should you desire to.

    >
    > A good idea. But I do not know how feasible this is. Not all OS have
    > the same error reporting mechanisms and the mapping from OS errors to
    > exception types would have to be maintained of all platforms.


    True, mapping exceptions directly from OS to OS would be problematic.
    And knowing which ones are on each OS is also annoying.
    I am proposing more of a (platform dependent) container of all possible
    exceptions, regardless of what they may mean. Or have them all include
    a common ancestor--same result.

    >> 3) provide an easier way to know which platform you're on than
    >> RUBY_PLATFORM =~ /mswin32|dgjpp|mingw/

    >
    > -1
    >
    > This would make a Ruby specific unification of operating systems
    > necessary. This means that not only maintainers of automake need to
    > keep track of operating systems but also maintainers of Ruby. Other
    > difficulties are: how much level of detail do you provide? For one
    > application it may be enough to know it's running on Linux, the other
    > one needs to know the kernel version and a third one does not bother
    > about versions but must know the distro. I see too much effort for too
    > little benefit.


    True maintaining this is annoying, but I'd also propose that it's
    useful. Currently in 1.9 we have:
    >> RUBY_VERSION

    => "1.9.2"
    >> RUBY_PLATFORM

    => "x86_64-linux"
    >> RUBY_ENGINE

    => "ruby"

    Typically "enough" OS information is given in RUBY_PLATFORM to determine
    the platform--it's just "hard" to use that for such. My example being
    that knowing if you're on windows is something like RUBY_PLATFORM =~
    /dgjpp|mingw|mswin/
    which seems overly complex for me. And very hard to get right the first
    time (ex: RUBY_PLATFORM =~ /win/ doesn't work--that includes darwin).

    >> 4) (this one's controversial) remove the extra # for code in strings
    >> (i.e. "string#{code}") -> "string{code}" less typing.

    >
    > -1
    >
    > Definitively a don't as the overhead of typing # isn't too big (plus, it
    > is more easily spotted) and the potential for damage caused by this is
    > large.


    True it's not too hard to type--I just think its absence would be less
    typing, and that the # is "too" easily spotted, but again, that's just
    my take on it. Actually you may have a reasonable point (easy to spot
    is good).

    The kicker is also that # is ingrained so much in existing ruby
    code...it would be a pretty dramatic change.


    >> 5) add a BigDecimal(float) method.
    >> -> BigDecimal.new("%f" % float)

    >
    > 0
    >
    > Seems reasonable at first sight but the absence might have a reason.
    > For example, by making the conversion to String explicit it is more
    > obvious that float and BigDecimal are not really compatible.


    Yeah I wonder that myself. I was just hoping to make it easier to use
    BigDecimal, since Floats are so imprecise to use for decimal numbers :)

    > if test ?d, "some dir"


    Could you explain that again? Not sure I do understand the idiom.
    Looks like bash?
    Much thanks.
    -=r
    --
    Posted via http://www.ruby-forum.com/.
     
    Roger Pack, Apr 11, 2009
    #7
  8. >> Roger Pack
    >>
    >> Thought I'd pass these thoughts by the readers here before sending them
    >> to core. They're my current wish list :)
    >>
    >> 1) add an Object#in? method to complement the existing Array#include?


    > Joel VanderWerf
    >
    > It's not really symmetrical. Array has an #include? method because it is
    > a collection. Object has #in? because it is--what? A potential member of
    > a collection?


    > Robert Klemme
    >
    > I don't see the benefit but I'm also not strongly against. I do see
    > Joel's point about the reversion. Basically it is strange that every
    > object should be able to answer a question that only the collection can
    > answer. Plus, you can easily add it yourself if you need it.


    Sometimes the best (or better) usage depends on the context.
    For example, on some occasions we use: Integer === object
    and on other occasions we use: object.kind_of?( Integer )
    So I'm not against this on principle, and for me the question is
    what is the balance between not adding things unless we need to
    and does this make things easier in a significant number of cases.
    I don't know the answer!


    >> Roger Pack
    >> 4) (this one's controversial) remove the extra # for code in strings
    >> (i.e. "string#{code}") -> "string{code}" less typing.


    I'm not in favour, for Robert Klemme's reasons.


    >>> Roger Pack
    >>>
    >>> 5) add a BigDecimal(float) method.
    >>> -> BigDecimal.new("%f" % float)


    >> Robert Klemme
    >>
    >> Seems reasonable at first sight but the absence might have a reason.
    >> For example, by making the conversion to String explicit it is more
    >> obvious that float and BigDecimal are not really compatible.


    > Roger Pack
    >
    > Yeah I wonder that myself. I was just hoping to make it easier to use
    > BigDecimal, since Floats are so imprecise to use for decimal numbers :)


    Then probably best to start with BigDecimal and keep using it?
    We can always use BD = BigDecimal ; BD.new( "123.456" )
    and I seem to recall that there's a way to assign a method to a variable
    which could reduce this to BD( "123.456" ). I think it's important
    to normally use strings to get BigDecimal values to avoid precision errors.

    Robert Klemme makes a good point: Float has less precision than BigDecimal
    and in general I think that you should be *very* wary about converting
    from lower precision to higher precision - at least not without being
    fully aware of what you are doing - because later on you may be mislead
    into thinking that your calculation is more accurate than it actually is.
    (See "Here's one I made earlier" below.)

    You can't gain precision by such a conversion, which is why my start
    position is not to do it. That said, converting Float to BigDecimal
    may sometimes be useful when it can prevent further loss of precision.
    For example, ( float_a - float_b ) can reduce the accuracy drastically,
    and conversion to BigDecimal might be useful there.
    ( Caveat: Numerical Analysis - study of ... - can be extremely tricky,
    and I only know enough about it to know that:
    1. I don't understand it sufficiently to make definitive statements.
    2. In my own stuff I probably ignore it more than I should. )

    So I am against easy conversion by using something like BigDecimal( float ).
    I think any standard conversion method from Float to BigDecimal
    should be relatively ugly and messy. I did tbink of suggesting a rather long
    method name, maybe BigDecimal.do_you_really_want_to_convert_this_float(fnum)
    but someone can always alias that to a much shorter name.

    If you require "bigdecimal/util" this does, amongst other things:
    # BigDecimal utility library. ... The following methods are provided
    # to convert other types to BigDecimals: ...
    class Float < Numeric
    def to_d
    BigDecimal(self.to_s)
    end
    end

    So you can require that library, or just use BigDecimal( float.to_s ),
    I think BigDecimal( float.to_s ) satisfies my general thought here
    that whatever the conversion method used is, it shouldn't be so simple
    that you can use it without being in some way being reminded
    that what you are doing might not be a good idea.
    So making it sort of ugly fits in with that.
    (In fact, I'm not sure that having a Float#to_d method is a good idea.)

    Doing a quick bit of testing suggested that using "%f" % float
    might be better than using float.to_s because in some cases
    the former preserves information that is actually in the float
    which the latter uses. In fact, I was going to suggest you propose
    to use "%f" % self in Float#to_d instead of self.to_s.
    But after some more thought and a bit of testing, I found that
    for me in IRB "%f" % float only gives results to 6 decimal places
    but float.to_s seems to give results to 14 or 15 significant figures
    so overall using float.to_s for the conversion seems better.

    If we want a BigDecimal method (and in view of BigDecimal( float.to_s )
    I don't think we do - but BigDecimal( float.to_s ) should perhaps
    be mentioned prominently in BigDecimal documentation)
    how about something like (not tested):
    def BigDecimal.from_f( f )
    if f.kind_of?( Float ) then BigDecimal( f.to_s )
    else raise "BigDecimal.from_f: argument must be a Float"
    end
    end

    An argument for this is that by providing it you give a reasonably
    simple standard way to do it which might reduce potentially
    problematic "build your own" solutions.
    (I'm not against "build your own" in principle: at the least
    it can be a useful way to find out how things work,
    and it may result in an improvement, and as long as it's
    your own time and your own decision to do it, why not?
    But where there are hidden pitfalls, a reliable and
    reasonably easy to use solution is a good idea.)


    ***** For those who want to know a bit more *****

    *** Here's one I made earlier. ***

    (Really! Two days ago, in fact. For those not in the UK the reference
    is to a long-running BBC television programme for children:
    http://en.wikipedia.org/wiki/Blue_peter
    ... The show is also famous for its "makes", which are demonstrations
    of how to construct a useful object or prepare food. These have given rise
    to the oft-used phrase "Here's one I made earlier", as presenters bring out
    a perfect and completed version of the object they are making. ...
    Well, one thing we try to do in Ruby is make (almost) perfect objects! )

    I'm looking (for my own purposes) at the various Numeric classes,
    and I think it's useful to consider them in terms of precision
    potentially being lost on conversion and how we should cope with that.

    (I'm using Microsoft Windows Vista (*1): if the behaviour shown doesn't work,
    just increase n until it does! Admittedly this uses Integer not BigDecimal,
    but it shows the potential problems if precision is lost.)

    irb

    n = 53
    i = 2 ** n #=> 9007199254740992
    ii = i + 1 #=> 9007199254740993
    f = Float( i ) #=> 9.00719925474099e+015
    ff = Float( ii ) #=> 9.00719925474099e+015
    iii = Integer( ff ) #=> 9007199254740992
    i == ii #=> false
    i == f #=> true
    ii == f #=> true
    f == ff #=> true
    i <=> ii #=> -1
    i <=> f #=> 0
    ii <=> f #=> 0

    Colin Bartlett

    (*1) Question: Why do you like Linux and BSD Unix so much?
    You've never used either of them.
    Answer: No, but I have used Microsoft Windows.
    with apologies to Karl Kraus http://en.wikipedia.org/wiki/Karl_Kraus
     
    Colin Bartlett, Apr 11, 2009
    #8
  9. Roger Pack

    Adam Gardner Guest

    Roger Pack wrote:
    > Thought I'd pass these thoughts by the readers here before sending them
    > to core. They're my current wish list :)
    >
    > 1) add an Object#in? method to complement the existing Array#include?
    >
    > 2) add some useful lists of exceptions, ex: IO.SELECT_EXCEPTIONS,
    > IO.READ_EXCEPTIONS, so that you can rescue the wide gamut of them
    > appropriately, should you desire to.
    >
    > 3) provide an easier way to know which platform you're on than
    > RUBY_PLATFORM =~ /mswin32|dgjpp|mingw/
    >
    > 4) (this one's controversial) remove the extra # for code in strings
    > (i.e. "string#{code}") -> "string{code}" less typing.
    >
    > 5) add a BigDecimal(float) method.
    > -> BigDecimal.new("%f" % float)
    >
    > 6) add Dir.directory?
    > -> File.directory?
    >
    > Feedback?
    > Thanks!
    > -=r


    Object#in? can be very useful in keeping code legible; it more likely to
    be problematic in some circumstances than others. I'm using it in the
    game I'm writing right now and it's working just fine, but I don't
    really think it should be part of Ruby Core.

    That said, it's very very easy to add yourself if you need it:

    class Object
    def in?(object)
    if object.respond_to?:)include?) then
    object.include? self
    else
    false
    end
    end #def in?
    end #class Object
    --
    Posted via http://www.ruby-forum.com/.
     
    Adam Gardner, Apr 11, 2009
    #9
  10. Roger Pack wrote:
    >>> 4) (this one's controversial) remove the extra # for code in strings
    >>> (i.e. "string#{code}") -> "string{code}" less typing.

    >> Would not like having to escape { in strings...

    >
    > Ok. This next isn't meant as an attacking question but...do you use { in
    > normal strings often? Granted probably more than #, but...?


    Yes, quite extensively when generating C code. Would hate to have to use
    \{...} instead of {...} for C blocks. Also, but less often, inside of

    instance_eval "...",

    or

    eval "...", etc.

    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
     
    Joel VanderWerf, Apr 12, 2009
    #10
  11. On 11.04.2009 20:43, Roger Pack wrote:
    >>> 1) add an Object#in? method to complement the existing Array#include?

    >> -0
    >>
    >> I don't see the benefit but I'm also not strongly against. I do see
    >> Joel's point about the reversion. Basically it is strange that every
    >> object should be able to answer a question that only the collection can
    >> answer. Plus, you can easily add it yourself if you need it.

    >
    > I kind of agree with Joel on this one, too.
    >
    > A few other observations:
    >
    > re: in?
    > Currently with #select you've got one in Kernel [which is IO.select] but
    > Arrays seem to have their own #select. So it is "conceivably possible"
    > to have a "default #in?" and have it overridden by Clutch#in? or
    > House#in? if desired.


    That's not exactly an override situation because the "global" select is
    used without an instance or with a class instance (IO) while
    Enumerable#select is always used with an instance.

    > Another option would be included? -- might be more ruby-y :)
    >
    >>> 2) add some useful lists of exceptions, ex: IO.SELECT_EXCEPTIONS,
    >>> IO.READ_EXCEPTIONS, so that you can rescue the wide gamut of them
    >>> appropriately, should you desire to.

    >> A good idea. But I do not know how feasible this is. Not all OS have
    >> the same error reporting mechanisms and the mapping from OS errors to
    >> exception types would have to be maintained of all platforms.

    >
    > True, mapping exceptions directly from OS to OS would be problematic.
    > And knowing which ones are on each OS is also annoying.
    > I am proposing more of a (platform dependent) container of all possible
    > exceptions, regardless of what they may mean. Or have them all include
    > a common ancestor--same result.


    There is SystemCallError already:

    ObjectSpace.each_object(Class) do |cl|
    p cl if cl.ancestors.include? SystemCallError
    end

    >>> 3) provide an easier way to know which platform you're on than
    >>> RUBY_PLATFORM =~ /mswin32|dgjpp|mingw/

    >> -1
    >>
    >> This would make a Ruby specific unification of operating systems
    >> necessary. This means that not only maintainers of automake need to
    >> keep track of operating systems but also maintainers of Ruby. Other
    >> difficulties are: how much level of detail do you provide? For one
    >> application it may be enough to know it's running on Linux, the other
    >> one needs to know the kernel version and a third one does not bother
    >> about versions but must know the distro. I see too much effort for too
    >> little benefit.

    >
    > True maintaining this is annoying, but I'd also propose that it's
    > useful. Currently in 1.9 we have:
    >>> RUBY_VERSION

    > => "1.9.2"
    >>> RUBY_PLATFORM

    > => "x86_64-linux"
    >>> RUBY_ENGINE

    > => "ruby"
    >
    > Typically "enough" OS information is given in RUBY_PLATFORM to determine
    > the platform--it's just "hard" to use that for such. My example being
    > that knowing if you're on windows is something like RUBY_PLATFORM =~
    > /dgjpp|mingw|mswin/
    > which seems overly complex for me. And very hard to get right the first
    > time (ex: RUBY_PLATFORM =~ /win/ doesn't work--that includes darwin).


    And how do you want to resolve the issues I have raised in my posting?
    The question really is "what is a platform"? When using cygwin, are you
    "on Windows" or not? etc.

    >>> 5) add a BigDecimal(float) method.
    >>> -> BigDecimal.new("%f" % float)

    >> 0
    >>
    >> Seems reasonable at first sight but the absence might have a reason.
    >> For example, by making the conversion to String explicit it is more
    >> obvious that float and BigDecimal are not really compatible.

    >
    > Yeah I wonder that myself. I was just hoping to make it easier to use
    > BigDecimal, since Floats are so imprecise to use for decimal numbers :)


    Which is exactly the reason why conversion to a BigDecimal should not be
    too easy. String with decimal encoded number as input format for a
    BigDecimal is really the proper type as you can see from the name
    "BigDecimal". :)

    >> if test ?d, "some dir"

    >
    > Could you explain that again? Not sure I do understand the idiom.
    > Looks like bash?


    [robert@ora01 ~]$ ruby19 -e 'puts "yeah!" if test ?d, "."'
    yeah!
    [robert@ora01 ~]$

    Happy Easter!

    robert
     
    Robert Klemme, Apr 12, 2009
    #11
  12. On Sat, Apr 11, 2009 at 1:35 PM, Colin Bartlett <> w=
    rote:
    >>> Roger Pack
    >>>
    >>> Thought I'd pass these thoughts by the readers here before sending them
    >>> to core. =C2=A0They're my current wish list :)
    >>>
    >>> 1) add an Object#in? method to complement the existing Array#include?

    >
    >> Joel VanderWerf
    >>
    >> It's not really symmetrical. Array has an #include? method because it is
    >> a collection. Object has #in? because it is--what? A potential member of
    >> a collection?

    >
    >> Robert Klemme
    >>
    >> I don't see the benefit but I'm also not strongly against. =C2=A0I do se=

    e
    >> Joel's point about the reversion. =C2=A0Basically it is strange that eve=

    ry
    >> object should be able to answer a question that only the collection can
    >> answer. =C2=A0Plus, you can easily add it yourself if you need it.

    >
    > Sometimes the best (or better) usage depends on the context.
    > For example, on some occasions we use: =C2=A0Integer =3D=3D=3D object
    > and on other occasions we use: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0object.k=

    ind_of?( Integer )
    > So I'm not against this on principle, and for me the question is
    > what is the balance between not adding things unless we need to
    > and does this make things easier in a significant number of cases.
    > I don't know the answer!
    >
    >
    >>> Roger Pack
    >>> 4) (this one's controversial) remove the extra # for code in strings
    >>> (i.e. "string#{code}") -> "string{code}" less typing.

    >
    > I'm not in favour, for Robert Klemme's reasons.
    >
    >
    >>>> Roger Pack
    >>>>
    >>>> 5) add a BigDecimal(float) method.
    >>>> =C2=A0-> BigDecimal.new("%f" % float)

    >
    >>> Robert Klemme
    >>>
    >>> Seems reasonable at first sight but the absence might have a reason.
    >>> For example, by making the conversion to String explicit it is more
    >>> obvious that float and BigDecimal are not really compatible.

    >
    >> Roger Pack
    >>
    >> Yeah I wonder that myself. I was just hoping to make it easier to use
    >> BigDecimal, since Floats are so imprecise to use for decimal numbers :)

    >
    > Then probably best to start with BigDecimal and keep using it?
    > We can always use =C2=A0BD =3D BigDecimal ; BD.new( "123.456" )
    > and I seem to recall that there's a way to assign a method to a variable
    > which could reduce this to BD( "123.456" ). I think it's important
    > to normally use strings to get BigDecimal values to avoid precision error=

    s.

    True, so I'd agree that encouraging Float -> BigDecimal conversions
    isn't a great idea. OTOH, what I would like to see is BigDecimal (and
    maybe even Rational) literal syntax in Ruby in the future, e.g.

    1.23 # Float
    1.23d # BigDecimal
    a =3D1 # Fixnum
    a/2 # =3D> 0
    b =3D 1r # Rational
    b/2 # =3D=3D Rational("1/2")

    Essentially, provide a way to make working with exact numbers
    convenient without necessarily adopting all the behavioral changes of
    the mathn library (which you may want to avoid in order not to break
    older code.)
     
    Christopher Dicely, Apr 12, 2009
    #12
  13. On Apr 11, 2:27 pm, Adam Gardner <> wrote:
    > Roger Pack wrote:
    > > Thought I'd pass these thoughts by the readers here before sending them
    > > to core.  They're my current wish list :)

    >
    > > 1) add an Object#in? method to complement the existing Array#include?

    >
    > Object#in? can be very useful in keeping code legible; it more likely to
    > be problematic in some circumstances than others. I'm using it in the
    > game I'm writing right now and it's working just fine, but I don't
    > really think it should be part of Ruby Core.
    >
    > That said, it's very very easy to add yourself if you need it:
    >
    > class Object
    >   def in?(object)
    >     if object.respond_to?:)include?) then
    >       object.include? self
    >     else
    >       false
    >     end
    >   end #def in?
    > end #class Object


    Before reading your email I was writing my own Object#in? and came up
    with a very similar method without testing :include? support:

    class Object
    def in?(collection)
    collection.include? self
    end
    end

    This way you can detect you're calling Object#in? with an "incorrect"
    argument. For example,

    3.include? [1,2,3] => true
    3.include? 5 => NoMethodError: undefined method `include?' for
    5:Fixnum

    My $0.02.

    Best regards,
    Edgardo
     
    Edgardo Hames, Apr 13, 2009
    #13
  14. Why aren't they? What do you mean by this out of interest?

    Blog: http://random8.zenunit.com/
    Learn rails: http://sensei.zenunit.com/

    On 11/04/2009, at 6:45 PM, Robert Klemme <>
    wrote:

    > Seems reasonable at first sight but the absence might have a reason.
    > For example, by making the conversion to String explicit it is more
    > obvious that float and BigDecimal are not really compatible.
     
    Julian Leviston, Apr 14, 2009
    #14
  15. Please do not top post.

    2009/4/14 Julian Leviston <>:
    > Why aren't they? What do you mean by this out of interest?


    09:41:50 ~$ ruby19 x.rb
    Float 0.00000000010000000827
    BigDecimal 0.00000000010000000000
    Float 0.00000000000000000827
    BigDecimal 0.00000000000000000000
    false
    true
    09:41:52 ~$ cat x.rb

    require 'bigdecimal'

    f = (1.0 + 1.0e-10) - 1.0
    bd = (BigDecimal.new("1.0") + BigDecimal.new("1.0e-10")) - BigDecimal.new("1.0")

    printf "%-10s %30.20f\n", f.class, f
    printf "%-10s %30.20f\n", bd.class, bd

    f -= 1.0e-10
    bd -= BigDecimal.new "1.0e-10"

    printf "%-10s %30.20f\n", f.class, f
    printf "%-10s %30.20f\n", bd.class, bd

    puts f == 0.0, bd == 0.0
    09:41:57 ~$

    > On 11/04/2009, at 6:45 PM, Robert Klemme <> wrote:
    >
    >> Seems reasonable at first sight but the absence might have a reason. For
    >> example, by making the conversion to String explicit it is more obvious that
    >> float and BigDecimal are not really compatible.


    Cheers

    robert

    --
    remember.guy do |as, often| as.you_can - without end
     
    Robert Klemme, Apr 14, 2009
    #15
  16. Roger Pack

    Roger Pack Guest

    > 09:41:50 ~$ ruby19 x.rb
    > Float 0.00000000010000000827
    > BigDecimal 0.00000000010000000000
    > Float 0.00000000000000000827
    > BigDecimal 0.00000000000000000000
    > false
    > true
    > 09:41:52 ~$ cat x.rb


    Good examples.
    I should explain better my original thought perhaps--I don't actually
    want to convert "rounded" data but yes make it "cleaner" and "simpler"
    to make BigDecimals.
    I think I can achieve this by allowing for BigDecimal(float) but,
    similar to how String#to_s works currently in trunk:
    "only accept default values of floats"
    i.e.

    BigDecimal(0.9)
    => #<BigDecimal:b7db9e14,'0.9E0',4(8)>

    >> BigDecimal((2.0-1.1).to_s) # 2.0-1.1 != 0.9

    # BOOM not allowed, since that's a float that's been rounded away from
    its pure form (0.9's default form)

    You can ascertain this a la
    ("%g" % (2.0-1.1)).to_f != (2.0-1.1) # blow up in this case--those are
    rounded floats we don't want to convert them.

    Somewhat sane?

    -=r
    --
    Posted via http://www.ruby-forum.com/.
     
    Roger Pack, Apr 15, 2009
    #16
  17. Roger Pack

    Roger Pack Guest

    > Thought I'd pass these thoughts by the readers here before sending them
    > to core. They're my current wish list :)



    and here's a few more, for any feedbacks:

    1) have load not "necessarily" require the .rb suffix, (i.e. make it
    behave more like require). Rationale--both load and require are
    ultimately used to import ruby scripts, Therefore having one be suffix
    insensitive and the other not is surprising.

    2) having "string" + something default to
    "string" + something.to_s

    History: when I mentioned this proposal once, Matz said something like
    "it used to work that way, but it was changed because it hid bugs"
    I think the reason that it hides bugs is because if the "something" is
    nil, the concatenation silently concatenated with nothing--you would
    have hoped it would have raised an exception, but instead you just have
    strings with mysteriously shorter lengths.

    (i.e. nil should *not* default to .to_s--this hides bugs)

    therefore I would propose that string#+ default to
    string + something.to_s
    unless that something is nil -- then raise an exception.
    I just really miss this from java, and dislike having to type in .to_s
    quite frequently (and I do know you can leverage .to_str for this same
    effect, I just wish it were default--I'm quite lazy and want to share
    this "nicety" from java).

    Thoughts?
    Thanks!
    -=r
    --
    Posted via http://www.ruby-forum.com/.
     
    Roger Pack, May 1, 2009
    #17
  18. Roger Pack

    Marc Heiler Guest

    some_var = '/tmp'


    print 'Is a directory.' if Dir.directory? some_var

    vs

    print 'Is a directory.' if File.directory? some_var

    The difference is small, and it is not really important but from a
    logical point of view, since we don't treat both as Inodes anyway in
    ruby, using Dir.directory? seems syntactically more logical than using
    File.directory?.

    But it is not anything which really bothers me.
    --
    Posted via http://www.ruby-forum.com/.
     
    Marc Heiler, May 1, 2009
    #18
  19. Roger Pack wrote:
    > 2) having "string" + something default to
    > "string" + something.to_s


    What about getting in the habit of

    "#{s}#{t}"

    instead of

    s + t

    to take care of the #to_s for you? Or course, that doesn't help with

    s += t

    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
     
    Joel VanderWerf, May 1, 2009
    #19
  20. Hi --

    Roger Pack wrote:
    > Thought I'd pass these thoughts by the readers here before sending them
    > to core. They're my current wish list :)


    Could you possibly start a different thread for each topic? Bunching
    them together makes it very labor-intensive to try to follow the thread
    if one is interested in a specific point, and impossible to tell who has
    responded to what without going through six topics' worth of posts.

    > 4) (this one's controversial) remove the extra # for code in strings
    > (i.e. "string#{code}") -> "string{code}" less typing.


    It's not extra, though. One way or another you have to flag the
    difference between interpolation and literal {. Having to escape literal
    { because they have special meaning seems to me to be the long way 'round.


    David

    --
    David A. Black / Ruby Power and Light, LLC
    Ruby/Rails consulting & training: http://www.rubypal.com
    Now out in PDF: The Well-Grounded Rubyist (http://manning.com/black2)
    "Ruby 1.9: What You Need To Know" Envycasts with David A. Black
    http://www.envycasts.com
     
    David A. Black, May 2, 2009
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    13
    Views:
    446
    Thomas Nelson
    Aug 3, 2006
  2. Murali
    Replies:
    2
    Views:
    595
    Jerry Coffin
    Mar 9, 2006
  3. Brian Mitchell

    New Ruby conditional semantics thoughts

    Brian Mitchell, Oct 30, 2004, in forum: Ruby
    Replies:
    10
    Views:
    262
    Brian Mitchell
    Nov 1, 2004
  4. Gregory Brown
    Replies:
    20
    Views:
    465
    Gregory Brown
    Apr 30, 2007
  5. Matthew Williams
    Replies:
    2
    Views:
    188
    Matthew Williams
    Jan 6, 2008
Loading...

Share This Page