Pass Value of Variable to a Function


(Michael Sheaver) #1

I am trying to build a table of current locale properties in code, and have encountered issues with trying to pass the value of a variable to a function:

let currentLocale = Locale(identifier: "en_US")

let calendar1 = currentLocale.calendar // "gregorian (fixed)"

let propertyName = "calendar"
let calendar2 = currentLocale.propertyName // Error: Value of type 'Locale' has no member 'porpertyName'
In the last line of code above, the instance of Locale thinks I am passing it "propertyName" rather than the contents of the variable "calendar".

Is there any way to pass the value of propertyName ("calendar") to the instance of Locale? I know that in other languages, you can prepend the variable name like '$propertyName', and that tells it to read the value of the variable.

I want to keep this pure Swift if possible.

I posted this question on StackOverflow, and got the following that does work:

let calendar2 =
    (currentLocale as NSLocale).object(forKey:NSLocale.Key(rawValue:propertyName))
It does seem odd to me that we must do some crazy Objective-C gymnastics to make it work. It would seem logical to have a computed property on the Any type named, let's say, contentsOf that would return or pass the contents of the variable to the called function. For example, to use the original code sample above, we could use:

    let calendar2 = currentLocale.propertyName.contentsOf

or something similar. Thus currentLocale.propertyName would pass the literal "propertyName", whereas currentLocale.propertyName.contentsOf would pass the contents "calendar".

Does anyone else agree that we need this functionality, or am I way out in left field on this? Or is this already possible and I haven't yet figured it out?

Sincerest Regards,
Michael

Michael Sheaver
msheaver@me.com


(Shawn Erickson) #2

I am trying to understand why you are trying to do this. Can you provide a
better example for why you need to do this?

-Shawn


(Zhao Xin) #3

I think you messed up with `Locale` and `NSLocale`.

`Locale` is a struct in Swift 3 to replace the legacy `NSLocale`. The
latter is a class, it has an inner `structure` called `NSLocale.Key`. For
`Locale`, there is no `NSLocale.Key`. All there keys are instance
properties in `Locale`. So in your specific case,

let calendar2 = (currentLocale as
NSLocale).object(forKey:NSLocale.Key(rawValue:propertyName))

is just almost the same as `let calendar2 = calendar1`.

If you insist on using `NSLocale.Key`, you should use `NSLocale` instead of
`Locale`.

Zhaoxin

···

On Wed, Sep 7, 2016 at 10:35 AM, Michael Sheaver via swift-users < swift-users@swift.org> wrote:

I am trying to build a table of current locale properties in code, and
have encountered issues with trying to pass the value of a variable to a
function:

let currentLocale = Locale(identifier: "en_US")
let calendar1 = currentLocale.calendar // "gregorian (fixed)"
let propertyName = "calendar"let calendar2 = currentLocale.propertyName // Error: Value of type 'Locale' has no member 'porpertyName'

In the last line of code above, the instance of Locale thinks I am passing
it "propertyName" rather than the contents of the variable "calendar".

Is there any way to pass the value of propertyName ("calendar") to the
instance of Locale? I know that in other languages, you can prepend the
variable name like '$propertyName', and that tells it to read the value of
the variable.

I want to keep this pure Swift if possible.
I posted this question on StackOverflow, and got the following that does
work:

let calendar2 =
    (currentLocale as NSLocale).object(forKey:NSLocale.Key(rawValue:propertyName))

It does seem odd to me that we must do some crazy Objective-C gymnastics
to make it work. It would seem logical to have a computed property on the
Any type named, let's say, contentsOf that would return or pass the
contents of the variable to the called function. For example, to use the
original code sample above, we could use:

    let calendar2 = currentLocale.propertyName.contentsOf

or something similar. Thus currentLocale.propertyName would pass the
literal "propertyName", whereas currentLocale.propertyName.contentsOf
would pass the contents "calendar".

Does anyone else agree that we need this functionality, or am I way out in
left field on this? Or is this already possible and I haven't yet figured
it out?

Sincerest Regards,
Michael

Michael Sheaver
msheaver@me.com

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Jens Alfke) #4

No, you can’t do that. The languages I think you’re referring to — PHP, Perl — are interpreted scripting languages. Very different beasts, where everything is dynamic and looked up at runtime. (Generally all objects are implemented as dictionaries with property names as keys, making it easy to look up properties by name.) Swift is more like C or C++.

Now, Objective-C has a fairly dynamic runtime that allows you to do this. Objects have a method valueForKey that takes a string and finds a property of the object with that name and returns its value. You can do this in Swift (on Apple platforms) if the class inherits from NSObject or has the @objc attribute. But this isn’t “pure” Swift; it’s an Objective-C feature you’re accessing through bridging.

Generally, there are other patterns that are used to get this sort of effect in languages that aren’t so dynamic (like C++ for example.) But we’d need to know more about the higher-level problem you’re trying to solve, to give advice on that.

—Jens

···

On Sep 6, 2016, at 9:39 PM, Michael Sheaver via swift-users <swift-users@swift.org> wrote:

I know that in some languages, if you prepend the passed parameter with a '$', as in $propertyName, the receiving function knows to use the contents of the variable named propertyName (in this case "calendar") instead of the literal string "propertyName".


(Michael Sheaver) #5

Hi Zhao,

Many thanks for your response, and I will give this a try. However, I think that I might have used a bad example for the bigger question I was trying to ask, and for that I am sorry.

The question that I am really trying to address here is: Is there a more Swift-y way to, when passing a parameter to a function, we can tell it whether:
  a) we intend to pass in the literal string, or
  b) we want to pass the contents of the named variable?

I know that in some languages, if you prepend the passed parameter with a '$', as in $propertyName, the receiving function knows to use the contents of the variable named propertyName (in this case "calendar") instead of the literal string "propertyName".

Can we easily do this in Swift? If not, why not? Can we propose a change request to implement either a computed property or a method on the Any() class that would allow us to tell a called function whether we are passing in a literal type or a variable that contains the data to be processed?

Maybe this would violate the type safety for which Swift is thankfully so strongly trying to preserve. I don't know, but I would at lest like to consider it, for there ARE good business cases for it.

Does this help to clarify the question. I am posing?

Shawn, let me put this into a Swift file and shoot it your way.

Many thanks!
Michael

···

On Sep 6, 2016, at 11:21 PM, Zhao Xin <owenzx@gmail.com> wrote:

I think you messed up with `Locale` and `NSLocale`.

`Locale` is a struct in Swift 3 to replace the legacy `NSLocale`. The latter is a class, it has an inner `structure` called `NSLocale.Key`. For `Locale`, there is no `NSLocale.Key`. All there keys are instance properties in `Locale`. So in your specific case,

let calendar2 = (currentLocale as NSLocale).object(forKey:NSLocale.Key(rawValue:propertyName))

is just almost the same as `let calendar2 = calendar1`.

If you insist on using `NSLocale.Key`, you should use `NSLocale` instead of `Locale`.

Zhaoxin

On Wed, Sep 7, 2016 at 10:35 AM, Michael Sheaver via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
I am trying to build a table of current locale properties in code, and have encountered issues with trying to pass the value of a variable to a function:

let currentLocale = Locale(identifier: "en_US")

let calendar1 = currentLocale.calendar // "gregorian (fixed)"

let propertyName = "calendar"
let calendar2 = currentLocale.propertyName // Error: Value of type 'Locale' has no member 'porpertyName'
In the last line of code above, the instance of Locale thinks I am passing it "propertyName" rather than the contents of the variable "calendar".

Is there any way to pass the value of propertyName ("calendar") to the instance of Locale? I know that in other languages, you can prepend the variable name like '$propertyName', and that tells it to read the value of the variable.

I want to keep this pure Swift if possible.

I posted this question on StackOverflow, and got the following that does work:

let calendar2 =
    (currentLocale as NSLocale).object(forKey:NSLocale.Key(rawValue:propertyName))
It does seem odd to me that we must do some crazy Objective-C gymnastics to make it work. It would seem logical to have a computed property on the Any type named, let's say, contentsOf that would return or pass the contents of the variable to the called function. For example, to use the original code sample above, we could use:

    let calendar2 = currentLocale.propertyName.contentsOf

or something similar. Thus currentLocale.propertyName would pass the literal "propertyName", whereas currentLocale.propertyName.contentsOf would pass the contents "calendar".

Does anyone else agree that we need this functionality, or am I way out in left field on this? Or is this already possible and I haven't yet figured it out?

Sincerest Regards,
Michael

Michael Sheaver
msheaver@me.com <mailto:msheaver@me.com>

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Zhao Xin) #6

Now I understand your point. But as Jens said, Swift is a static language,
it won't interpret `property` as a variable after `.`(dot). So for Swift
compiler, you just refer to a none-exist property.

Zhaoxin

···

On Wed, Sep 7, 2016 at 12:39 PM, Michael Sheaver <msheaver@me.com> wrote:

Hi Zhao,

Many thanks for your response, and I will give this a try. However, I
think that I might have used a bad example for the bigger question I was
trying to ask, and for that I am sorry.

The question that I am really trying to address here is: Is there a more
Swift-y way to, when passing a parameter to a function, we can tell it
whether:
a) we intend to pass in the literal string, or
b) we want to pass the contents of the named variable?

I know that in some languages, if you prepend the passed parameter with a
'$', as in $propertyName, the receiving function knows to use the
*contents* of the variable named propertyName (in this case "calendar")
instead of the literal string "propertyName".

Can we easily do this in Swift? If not, why not? Can we propose a change
request to implement either a computed property or a method on the Any()
class that would allow us to tell a called function whether we are passing
in a literal type or a variable that contains the data to be processed?

Maybe this would violate the type safety for which Swift is thankfully so
strongly trying to preserve. I don't know, but I would at lest like to
consider it, for there ARE good business cases for it.

Does this help to clarify the question. I am posing?

Shawn, let me put this into a Swift file and shoot it your way.

Many thanks!
Michael

On Sep 6, 2016, at 11:21 PM, Zhao Xin <owenzx@gmail.com> wrote:

I think you messed up with `Locale` and `NSLocale`.

`Locale` is a struct in Swift 3 to replace the legacy `NSLocale`. The
latter is a class, it has an inner `structure` called `NSLocale.Key`. For
`Locale`, there is no `NSLocale.Key`. All there keys are instance
properties in `Locale`. So in your specific case,

let calendar2 = (currentLocale as NSLocale).object(forKey:
NSLocale.Key(rawValue:propertyName))

is just almost the same as `let calendar2 = calendar1`.

If you insist on using `NSLocale.Key`, you should use `NSLocale` instead
of `Locale`.

Zhaoxin

On Wed, Sep 7, 2016 at 10:35 AM, Michael Sheaver via swift-users < > swift-users@swift.org> wrote:

I am trying to build a table of current locale properties in code, and
have encountered issues with trying to pass the value of a variable to a
function:

let currentLocale = Locale(identifier: "en_US")
let calendar1 = currentLocale.calendar // "gregorian (fixed)"
let propertyName = "calendar"let calendar2 = currentLocale.propertyName // Error: Value of type 'Locale' has no member 'porpertyName'

In the last line of code above, the instance of Locale thinks I am
passing it "propertyName" rather than the contents of the variable
"calendar".

Is there any way to pass the value of propertyName ("calendar") to the
instance of Locale? I know that in other languages, you can prepend the
variable name like '$propertyName', and that tells it to read the value of
the variable.

I want to keep this pure Swift if possible.
I posted this question on StackOverflow, and got the following that does
work:

let calendar2 =
    (currentLocale as NSLocale).object(forKey:NSLocale.Key(rawValue:propertyName))

It does seem odd to me that we must do some crazy Objective-C gymnastics
to make it work. It would seem logical to have a computed property on the
Any type named, let's say, contentsOf that would return or pass the
contents of the variable to the called function. For example, to use the
original code sample above, we could use:

    let calendar2 = currentLocale.propertyName.contentsOf

or something similar. Thus currentLocale.propertyName would pass the
literal "propertyName", whereas currentLocale.propertyName.contentsOf
would pass the contents "calendar".

Does anyone else agree that we need this functionality, or am I way out
in left field on this? Or is this already possible and I haven't yet
figured it out?

Sincerest Regards,
Michael

Michael Sheaver
msheaver@me.com

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Rugen Heidbuchel) #7

Can't mirrors solve this problem for Locale itself, instead of using NSLocale? I do think that will affect performance though.

Rugen

···

On 7 Sep 2016, at 09:03, Zhao Xin via swift-users <swift-users@swift.org> wrote:

Now I understand your point. But as Jens said, Swift is a static language, it won't interpret `property` as a variable after `.`(dot). So for Swift compiler, you just refer to a none-exist property.

Zhaoxin

On Wed, Sep 7, 2016 at 12:39 PM, Michael Sheaver <msheaver@me.com> wrote:
Hi Zhao,

Many thanks for your response, and I will give this a try. However, I think that I might have used a bad example for the bigger question I was trying to ask, and for that I am sorry.

The question that I am really trying to address here is: Is there a more Swift-y way to, when passing a parameter to a function, we can tell it whether:
  a) we intend to pass in the literal string, or
  b) we want to pass the contents of the named variable?

I know that in some languages, if you prepend the passed parameter with a '$', as in $propertyName, the receiving function knows to use the contents of the variable named propertyName (in this case "calendar") instead of the literal string "propertyName".

Can we easily do this in Swift? If not, why not? Can we propose a change request to implement either a computed property or a method on the Any() class that would allow us to tell a called function whether we are passing in a literal type or a variable that contains the data to be processed?

Maybe this would violate the type safety for which Swift is thankfully so strongly trying to preserve. I don't know, but I would at lest like to consider it, for there ARE good business cases for it.

Does this help to clarify the question. I am posing?

Shawn, let me put this into a Swift file and shoot it your way.

Many thanks!
Michael

On Sep 6, 2016, at 11:21 PM, Zhao Xin <owenzx@gmail.com> wrote:

I think you messed up with `Locale` and `NSLocale`.

`Locale` is a struct in Swift 3 to replace the legacy `NSLocale`. The latter is a class, it has an inner `structure` called `NSLocale.Key`. For `Locale`, there is no `NSLocale.Key`. All there keys are instance properties in `Locale`. So in your specific case,

let calendar2 = (currentLocale as NSLocale).object(forKey:NSLocale.Key(rawValue:propertyName))

is just almost the same as `let calendar2 = calendar1`.

If you insist on using `NSLocale.Key`, you should use `NSLocale` instead of `Locale`.

Zhaoxin

On Wed, Sep 7, 2016 at 10:35 AM, Michael Sheaver via swift-users <swift-users@swift.org> wrote:
I am trying to build a table of current locale properties in code, and have encountered issues with trying to pass the value of a variable to a function:

let currentLocale = Locale(identifier: "en_US")

let calendar1 = currentLocale.calendar // "gregorian (fixed)"

let propertyName = "calendar"
let calendar2 = currentLocale.propertyName // Error: Value of type 'Locale' has no member 'porpertyName'
In the last line of code above, the instance of Locale thinks I am passing it "propertyName" rather than the contents of the variable "calendar".

Is there any way to pass the value of propertyName ("calendar") to the instance of Locale? I know that in other languages, you can prepend the variable name like '$propertyName', and that tells it to read the value of the variable.

I want to keep this pure Swift if possible.

I posted this question on StackOverflow, and got the following that does work:

let calendar2 =
    (currentLocale as NSLocale).object(forKey:NSLocale.Key(rawValue:propertyName))
It does seem odd to me that we must do some crazy Objective-C gymnastics to make it work. It would seem logical to have a computed property on the Any type named, let's say, contentsOf that would return or pass the contents of the variable to the called function. For example, to use the original code sample above, we could use:

    let calendar2 = currentLocale.propertyName.contentsOf

or something similar. Thus currentLocale.propertyName would pass the literal "propertyName", whereas currentLocale.propertyName.contentsOf would pass the contents "calendar".

Does anyone else agree that we need this functionality, or am I way out in left field on this? Or is this already possible and I haven't yet figured it out?

Sincerest Regards,
Michael

Michael Sheaver
msheaver@me.com

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users